Compare commits

...

2 Commits

Author SHA1 Message Date
teverse a4dc190998 Remove old, now unused, code. 2019-11-17 10:49:34 +00:00
teverse e6528bdc2a use correct protocol for fonts. teverse to deprecate fontFiles without protocol prefix 2019-11-17 10:35:42 +00:00
38 changed files with 21 additions and 8199 deletions

View File

@ -1,83 +0,0 @@
-- Copyright (c) 2019 teverse.com
-- camera.lua
local cameraController = {}
local selectionController = require("tevgit:create/controllers/select.lua")
cameraController.zoomStep = 3
cameraController.rotateStep = 0.003
cameraController.moveStep = 0.5 -- how fast the camera moves
cameraController.camera = workspace.camera
-- Setup the initial position of the camera
cameraController.camera.position = vector3(11, 5, 10)
cameraController.camera:lookAt(vector3(0,0,0))
-- Camera key input values
cameraController.cameraKeyEventLooping = false
cameraController.cameraKeyArray = {
[enums.key.w] = vector3(0, 0, 1),
[enums.key.s] = vector3(0, 0, -1),
[enums.key.a] = vector3(-1, 0, 0),
[enums.key.d] = vector3(1, 0, 0),
[enums.key.q] = vector3(0, -1, 0),
[enums.key.e] = vector3(0, 1, 0)
}
engine.input:mouseScrolled(function( input )
if input.systemHandled then return end
local cameraPos = cameraController.camera.position
cameraPos = cameraPos + (cameraController.camera.rotation * (cameraController.cameraKeyArray[enums.key.w] * input.movement.y * cameraController.zoomStep))
cameraController.camera.position = cameraPos
end)
engine.input:mouseMoved(function( input )
if engine.input:isMouseButtonDown( enums.mouseButton.right ) then
local pitch = quaternion():setEuler(input.movement.y * cameraController.rotateStep, 0, 0)
local yaw = quaternion():setEuler(0, input.movement.x * cameraController.rotateStep, 0)
-- Applied seperately to avoid camera flipping on the wrong axis.
cameraController.camera.rotation = yaw * cameraController.camera.rotation;
cameraController.camera.rotation = cameraController.camera.rotation * pitch
--updatePosition()
end
end)
engine.input:keyPressed(function( inputObj )
if inputObj.systemHandled or engine.input:isKeyDown(enums.key.leftCtrl) then return end
if cameraController.cameraKeyArray[inputObj.key] and not cameraController.cameraKeyEventLooping then
cameraController.cameraKeyEventLooping = true
repeat
local cameraPos = cameraController.camera.position
for key, vector in pairs(cameraController.cameraKeyArray) do
-- check this key is pressed (still)
if engine.input:isKeyDown(key) then
cameraPos = cameraPos + (cameraController.camera.rotation * vector * cameraController.moveStep)
end
end
cameraController.cameraKeyEventLooping = (cameraPos ~= cameraController.camera.position)
cameraController.camera.position = cameraPos
wait(0.001)
until not cameraController.cameraKeyEventLooping
end
-- SELECTION SYSTEM REQUIRED
--[[
if inputObj.key == enums.key.f and #selectionController.selection>0 then
local mdn = vector3(median(selectionController.selection, "x"), median(selectionController.selection, "y"),median(selectionController.selection, "z") )
--camera.position = mdn + (camera.rotation * vector3(0,0,1) * 15)
--print(mdn)
engine.tween:begin(cameraController.camera, .2, {position = mdn + (cameraController.camera.rotation * vector3(0,0,1) * 15)}, "outQuad")
end]]
end)
return cameraController

View File

@ -1,163 +0,0 @@
-- Copyright (c) 2019 teverse.com
-- console.lua
-- Author(s) joritochip, TheCakeChicken
local consoleController = {}
local themeController = require("tevgit:create/controllers/theme.lua")
local uiController = require("tevgit:create/controllers/ui.lua")
consoleController.outputLines = {}
function stringSplit(inputStr, sep)
if sep == nil then
sep = "%s"
end
local t={}
for str in string.gmatch(inputStr, "([^"..sep.."]+)") do
table.insert(t, str)
end
return t
end
function stringCount(inputStr, pat)
if inputStr == nil or pat == nil then return end
return select(2, string.gsub(inputStr, pat, ""))
end
consoleController.createConsole = function(workshop)
local windowObject = uiController.createWindow(
workshop.interface,
guiCoord(0.25, 0, 0.25, 0),
guiCoord(0.5, 0, 0.5, 0),
"Console"
)
windowObject.visible = false
consoleController.consoleObject = windowObject
local scrollView = uiController.create("guiScrollView", windowObject.content, {
size = guiCoord(1, 0, 1, -25),
position = guiCoord(0, 0, 0, 0),
canvasSize = guiCoord(1, 0, 0, 0)
})
local entryLabel = uiController.create("guiTextBox", scrollView, {
size = guiCoord(1, -10, 0, 50),
position = guiCoord(0, 0, 0, 0),
name = "entryLabel",
wrap = true,
multiline = true,
readOnly = true,
align = enums.align.topLeft,
fontSize = 20,
textColour = colour(1, 1, 1)
}, "default")
local cmdInput = uiController.create("guiFrame", windowObject.content, {
size = guiCoord(1, 0, 0, 25),
position = guiCoord(0, 0, 1, -25),
name = "cmdInput"
}, "secondary")
local cmdDecorText = uiController.create("guiTextBox", cmdInput, {
size = guiCoord(0, 20, 1, 0),
position = guiCoord(0, 5, 0, 0),
multiline = false,
text = ">",
align = enums.align.middle,
fontSize = 20,
textColour = colour(1, 1, 1),
name = "cmdDecorText"
}, "secondary")
local cmdInputText = uiController.create("guiTextBox", cmdInput, {
size = guiCoord(1, -30, 1, 0),
position = guiCoord(0, 25, 0, 0),
multiline = false,
text = "Enter a script",
align = enums.align.middleLeft,
fontSize = 20,
textColour = colour(1, 1, 1),
name = "cmdInputText",
readOnly = false
}, "secondary")
local cmdBarActive = false
local commandHistoryIndex = 0
local commandHistory = {}
cmdInputText:keyFocused(function()
cmdBarActive = true
if cmdInputText.text == "Enter a script" then cmdInputText.text = "" end
end)
cmdInputText:keyUnfocused(function()
cmdBarActive = false
end)
engine.input:keyPressed(function(inputObj)
if inputObj.key == enums.key.f12 then
if inputObj.systemHandled then return end
consoleController.consoleObject.visible = not consoleController.consoleObject.visible
elseif cmdBarActive == true then
if inputObj.key == enums.key["return"] then
if cmdInputText.text ~= "Enter a script" and cmdInputText.text ~= "" then
table.insert(commandHistory, cmdInputText.text)
commandHistoryIndex = #commandHistory + 1
print("> "..cmdInputText.text)
wait()
workshop:loadString(cmdInputText.text)
cmdInputText.text = ""
end
elseif inputObj.key == enums.key.up and #commandHistory > 0 then
if commandHistoryIndex - 1 > 0 then
commandHistoryIndex = commandHistoryIndex - 1
cmdInputText.text = commandHistory[commandHistoryIndex]
end
elseif inputObj.key == enums.key.down and #commandHistory > 0 then
if commandHistoryIndex < #commandHistory + 1 then
commandHistoryIndex = commandHistoryIndex + 1
if commandHistoryIndex > #commandHistory then
cmdInputText.text = ""
else
cmdInputText.text = commandHistory[commandHistoryIndex]
end
end
end
end
end)
engine.debug:output(function(msg, type)
if #consoleController.outputLines > 100 then
table.remove(consoleController.outputLines, 1)
end
table.insert(consoleController.outputLines, {msg, type})
local text = ""
for _,v in pairs (consoleController.outputLines) do
local colour = (v[2] == 1) and "#ff0000" or "#ffffff"
if text ~= "" then
text = string.format("%s\n%s%s", text, colour, v[1])
else
text = string.format("%s%s", colour, v[1])
end
end
-- deprecated but it's the only way to do color afaik
entryLabel:setText(text)
local size = stringCount(text, "\n")*20+20
entryLabel.size = guiCoord(1, -10, 0, size)
scrollView.canvasSize = guiCoord(0, 0, 0, size)
end)
end
return consoleController

View File

@ -1,134 +0,0 @@
local controller = {
contextLastOpenedAt = nil,
activeContextMenu = nil
}
local ui = require("tevgit:create/controllers/ui.lua")
local function mouseOutOfBounds(tpLeft, btmRight)
local vec2 = engine.input.mousePosition
return (not (vec2.x > tpLeft.x and vec2.y > tpLeft.y and vec2.x < btmRight.x and vec2.y < btmRight.y))
end
function controller.create(options)
local frame = engine.guiFrame()
frame.size = guiCoord(0, 200, 0, 0)
frame.cropChildren = false
frame.zIndex = 2
ui.theme.add(frame, "main")
local position = guiCoord(0, 15, 0, 10)
local size = guiCoord(1, 0, 0, 20)
local offsetY = guiCoord(0, 0, 0, 40)
for key, data in next, options do
local option = data.subOptions and engine.guiTextBox() or engine.guiButton()
option.position = position
option.size = size
option.align = enums.align.middleLeft
option.cropChildren = false
option.text = key
ui.theme.add(option, "primaryText")
if (data.subOptions) then
local subframe = controller.create(data.subOptions)
ui.theme.add(subframe, "secondary")
subframe.position = guiCoord(1, -15, 0, -10)
subframe.visible = false
subframe.parent = option
local isShowing = false
option:mouseFocused(function()
if (not isShowing) then
isShowing = true
subframe.position = guiCoord(1, -15, 0, -10)
if (engine.input.mousePosition.y > engine.input.screenSize.y - subframe.size.offsetY) then
subframe.position = subframe.position + guiCoord(0, 0, 0, -(subframe.size.offsetY - 40))
end
if (engine.input.mousePosition.x > engine.input.screenSize.x - frame.size.offsetX) then
subframe.position = subframe.position + guiCoord(-1, -frame.size.offsetX, 0, 0)
end
subframe.visible = true
repeat wait()
until controller.activeContextMenu == nil or (
mouseOutOfBounds(subframe.absolutePosition, subframe.absolutePosition + subframe.absoluteSize)
and mouseOutOfBounds(option.absolutePosition, option.absolutePosition + option.absoluteSize)
)
if (controller.activeContextMenu ~= nil) then
isShowing = false
subframe.visible = false
end
end
end)
else
option:mouseLeftReleased(function()
if (frame and controller.activeContextMenu and (controller.activeContextMenu == frame or frame:isDescendantOf(controller.activeContextMenu))) then
controller.activeContextMenu:destroy()
controller.activeContextMenu = nil
end
data.action()
end)
end
if (data.subOptions or data.hotkey) then
local subtext = engine.guiTextBox()
subtext.text = data.hotkey or ">"
subtext.size = guiCoord(1, 0, 1, 0)
subtext.position = guiCoord(0, -30, 0, 0)
subtext.handleEvents = false
subtext.align = enums.align.middleRight
ui.theme.add(subtext, "secondaryText")
subtext.parent = option
end
frame.size = frame.size + offsetY
position = position + offsetY
option.parent = frame
end
return frame
end
function controller.display(contextMenu)
if (controller.activeContextMenu) then
controller.activeContextMenu:destroy()
controller.activeContextMenu = nil
end
local pos = engine.input.mousePosition
contextMenu.position = guiCoord(0, pos.x, 0, pos.y)
if (engine.input.mousePosition.y > engine.input.screenSize.y - contextMenu.size.offsetY) then
contextMenu.position = contextMenu.position + guiCoord(0, 0, 0, -contextMenu.size.offsetY)
end
if (engine.input.mousePosition.x > engine.input.screenSize.x - contextMenu.size.offsetX) then
contextMenu.position = contextMenu.position + guiCoord(0, -contextMenu.size.offsetX, 0, 0)
end
contextMenu.parent = ui.workshop.interface
contextLastOpenedAt = engine.input.mousePosition
controller.activeContextMenu = contextMenu
end
function controller.bind(object, options)
local listener = object:mouseRightReleased(function()
if type(options) == "function" then
controller.display(controller.create(options()))
else
controller.display(controller.create(options))
end
end)
return listener
end
engine.input:mouseLeftReleased(function()
if (controller.activeContextMenu) then
local tpLeft = controller.activeContextMenu.absolutePosition
local btmRight = tpLeft + controller.activeContextMenu.absoluteSize
if (mouseOutOfBounds(tpLeft, btmRight)) then
controller.activeContextMenu:destroy()
controller.activeContextMenu = nil
end
end
end)
return controller

View File

@ -1,23 +0,0 @@
local toolsController = require("tevgit:create/controllers/tool.lua")
local selectionController = require("tevgit:create/controllers/select.lua")
local propertyController = require("tevgit:create/controllers/propertyEditor.lua")
local light = toolsController.createButton("createTab", "fa:s-lightbulb", "Light")
light:mouseLeftReleased(function ()
local l = engine.construct("light", workspace, {
position = workspace.camera.position - (workspace.camera.rotation * vector3(0,0,5))
})
propertyController.generateProperties(l)
end)
local script = toolsController.createButton("createTab", "fa:s-microchip", "Script")
script:mouseLeftReleased(function ()
require("tevgit:create/controllers/scriptController.lua").newScriptDialogue(workspace)
end)
-- temp:
local graphicsSettings = toolsController.createButton("topBar", "fa:s-cogs", "Graphics")
graphicsSettings:mouseLeftReleased(function ()
propertyController.generateProperties(engine.graphics)
end)

View File

@ -1,62 +0,0 @@
-- Mean to be a module dedicated to debugging create mode?
local toolsController = require("tevgit:create/controllers/tool.lua")
local uiController = require("tevgit:create/controllers/ui.lua")
local uiTabController = require("tevgit:create/controllers/uiTabController.lua")
uiController.devTab = uiController.createFrame(uiController.workshop.interface, {
name = "devTab",
size = guiCoord(1, 0, 0, 60),
position = guiCoord(0,0,0,23)
}, "mainTopBar")
uiTabController.createTab(uiController.tabs, "Dev [ignore this]", uiController.devTab)
toolsController.registerMenu("devTab", uiController.devTab)
local reloadButton = toolsController.createButton("devTab", "fa:s-sync", "Reload all")
reloadButton:mouseLeftReleased(function ()
engine.input.cursorTexture = "fa:s-mouse-pointer"
uiController.workshop:reloadCreate()
end)
local reloadShadersButton = toolsController.createButton("devTab", "fa:s-sync", "Shaders")
reloadShadersButton:mouseLeftReleased(function ()
uiController.workshop:reloadShaders()
end)
local gcWindow = uiController.createWindow(uiController.workshop.interface, guiCoord(0.5, -150, 0, 300), guiCoord(0, 300, 0, 93), "GC", true) --undockable window
gcWindow.visible = false
gcWindow.zIndex = 2000
local gcText = uiController.create("guiTextBox", gcWindow.content, {
size = guiCoord(1,-20,1,-40),
position = guiCoord(0,10,0,10),
wrap = true
}, "mainText")
local gcnow = uiController.create("guiButton", gcWindow.content, {
size = guiCoord(1,-20,0,20),
position= guiCoord(0,10,1,-25),
text = "collectgarbage()"
}, "main")
gcnow:mouseLeftReleased(function ()
collectgarbage()
end)
local garbageButton = toolsController.createButton("devTab", "fa:s-trash-alt", "GC")
garbageButton:mouseLeftReleased(function ()
gcWindow.visible = not gcWindow.visible
spawnThread(function ()
while gcWindow.visible do
gcText.text = string.format("Memory Usage %.3f MB", collectgarbage( "count" ) / 1024)
wait(.1)
end
end)
end)

View File

@ -1,322 +0,0 @@
local controller = {}
controller.ui = nil
controller.dockDictionary = {}
controller.bottomDock = {}
controller.rightDock = {}
local luaHelpers = require("tevgit:create/helpers.lua")
local lastUpdate = os.clock()
local pendingSave = false
local saveDocks = function()
if pendingSave then return end
pendingSave = true
repeat
wait()
until os.clock() - lastUpdate > 5 -- delay so we're sure user has stopped messing with the layout
local setting = {
bottomDock = {},
rightDock = {}
}
for i,v in pairs(controller.bottomDock) do
table.insert(setting.bottomDock, {i, v.titleBar.textLabel.text})
end
for i,v in pairs(controller.rightDock) do
table.insert(setting.rightDock, {i, v.titleBar.textLabel.text})
end
print("Saving dock layout")
controller.ui.workshop:setSettings("docks", setting)
pendingSave = false
end
local function sorter(a, b)
return a[1] < b[1]
end
controller.loadSettings = function()
local setting = controller.ui.workshop:getSettings("docks")
if setting then
print("Restoring dock layout")
local easyWay = {}
for i,v in pairs(controller.bottomDock) do
easyWay[v.titleBar.textLabel.text] = v
v.position = v.position - guiCoord(0,0,0,30)
end
for i,v in pairs(controller.rightDock) do
easyWay[v.titleBar.textLabel.text] = v
--print(v.titleBar.textLabel.text, v)
v.position = v.position - guiCoord(0,30,0,0)
end
controller.bottomDock = {}
controller.rightDock = {}
controller.dockDictionary = {}
table.sort(setting.bottomDock, sorter)
for i,v in ipairs(setting.bottomDock) do
--print("look:", v)
if easyWay[v[2]] then
controller.dockWindow(easyWay[v[2]], controller.bottomDock)
-- print("dockng")
easyWay[v[2]] = nil
end
end
table.sort(setting.rightDock, sorter)
for i,v in ipairs(setting.rightDock) do
if easyWay[v[2]] then
controller.dockWindow(easyWay[v[2]], controller.rightDock)
easyWay[v[2]] = nil
end
end
end
end
-- direction: up, down, left or right
local function renderHelper(parent, direction, pos)
local frame = controller.ui.create("guiFrame", parent, {
name = "locationHelper" .. direction,
size = guiCoord(0, 40, 0, 40),
borderRadius = 5,
borderWidth = 1,
borderAlpha = 1
}, "light")
if pos then
frame.position = pos
end
controller.ui.create("guiImage", frame, {
size = guiCoord(0, 12, 0, 12),
position = guiCoord(0.5,-6,0,5),
texture = "fa:s-arrow-" .. direction
}, "light")
controller.ui.create("guiImage", frame, {
size = guiCoord(0, 18, 0, 18),
position = guiCoord(0.5,-9,0,18),
backgroundAlpha = 0.75,
texture = "fa:r-window-maximize"
}, "light")
return frame
end
controller.renderDockLocationHelpers = function()
local helpers = engine.construct("guiFrame", controller.ui.workshop.interface, { zIndex=100, size = guiCoord(1,0,1,0), backgroundAlpha = 0, handleEvents=false})
local outline = controller.ui.create("guiFrame", helpers, {
name = "outline",
size = guiCoord(0, 100, 0, 220),
backgroundAlpha = 0,
borderRadius = 2,
borderWidth = 1,
borderAlpha = 1,
visible = false
}, "light")
if #controller.bottomDock == 0 then
renderHelper(helpers, "down", guiCoord(0.5, -20, 0.9, -20))
else
for i,v in pairs(controller.bottomDock) do
renderHelper(helpers, "down", guiCoord(0, v.absolutePosition.y + 20, 0.9, -20))
if i == #controller.bottomDock then
renderHelper(helpers, "down", guiCoord(0, v.absolutePosition.y + v.absoluteSize.y - 40, 0.9, -20))
end
end
end
if #controller.rightDock == 0 then
renderHelper(helpers, "right", guiCoord(0.9, -20, 0.5, -20))
else
for i,v in pairs(controller.rightDock) do
renderHelper(helpers, "right", guiCoord(0.9, -20, 0, v.absolutePosition.y + 20))
if i == #controller.rightDock then
renderHelper(helpers, "right", guiCoord(0.9, -20, 0, v.absolutePosition.y + v.absoluteSize.y - 40))
end
end
end
return helpers
end
controller.undockWindow = function(window)
local dockDic = controller.dockDictionary[window]
controller.dockDictionary[window] = nil
if dockDic then
if dockDic == 0 then
local foundi = nil
for i,v in pairs(controller.bottomDock) do
if v == window then
controller.bottomDock[i] = nil
foundi = i
elseif foundi and i > foundi then
controller.bottomDock[i-1] = v
controller.bottomDock[i] = nil
end
end
local scale = 1
if #controller.rightDock > 0 then
scale = 0.8
end
for i,v in pairs(controller.bottomDock) do
-- No tween because other parts of the script needs to read the size and position instantly.
v.size = guiCoord(scale*(1/#controller.bottomDock), 0, 0.2, 0)
v.position = guiCoord(scale*((i-1) * (1/#controller.bottomDock)), 0, 0.8, 0)
end
elseif dockDic == 1 then
local foundi = nil
for i,v in pairs(controller.rightDock) do
if v == window then
controller.rightDock[i] = nil
foundi = i
elseif foundi and i > foundi then
controller.rightDock[i-1] = v
controller.rightDock[i] = nil
end
end
for i,v in pairs(controller.rightDock) do
-- No tween because other parts of the script needs to read the size and position instantly.
v.size = guiCoord(0.2, 0, 1/#controller.rightDock, i == 1 and -83 or 0)
v.position = guiCoord(0.8,0,(i-1) * (1/#controller.rightDock), i == 1 and 83 or 0)
end
end
end
end
controller.dockWindow = function(window, dock, pos)
controller.undockWindow(window)
if dock == controller.bottomDock then
controller.dockDictionary[window] = 0
--table.insert(controller.bottomDock, window)
local newIndex = (pos and pos or 0 / (1/#controller.bottomDock+1)) + 1
if newIndex ~= math.floor(newIndex) then
newIndex = #controller.bottomDock + 1
end
if pos and #controller.bottomDock > 0 and newIndex <= #controller.bottomDock then
for i = #controller.bottomDock, 1, -1 do
if i >= newIndex then
controller.bottomDock[i+1] = controller.bottomDock[i]
end
if i == newIndex then
controller.bottomDock[i] = window
end
end
else
controller.bottomDock[#controller.bottomDock+1] = window
end
local scale = 1
if #controller.rightDock > 0 then
scale = 0.8
end
for i,v in pairs(controller.bottomDock) do
v.size = guiCoord(scale*(1/#controller.bottomDock), 0, 0.2, 0)
v.position = guiCoord(scale*((i-1) * (1/#controller.bottomDock)), 0, 0.8, 0)
end
elseif dock == controller.rightDock then
controller.dockDictionary[window] = 1
--table.insert(controller.rightDock, window)
local newIndex = (pos and pos or 0 / (1/#controller.rightDock+1)) + 1
if newIndex ~= math.floor(newIndex) then
newIndex = #controller.rightDock + 1
end
if pos and #controller.rightDock > 0 and newIndex <= #controller.rightDock then
for i = #controller.rightDock, 1, -1 do
if i >= newIndex then
controller.rightDock[i+1] = controller.rightDock[i]
end
if i == newIndex then
controller.rightDock[i] = window
end
end
else
controller.rightDock[#controller.rightDock+1] = window
end
for i,v in pairs(controller.rightDock) do
v.size = guiCoord(0.2, 0, 1/#controller.rightDock, i == 1 and -83 or 0)
v.position = guiCoord(0.8,0,(i-1) * (1/#controller.rightDock), i == 1 and 83 or 0)
end
end
end
-- window should be a window created in ui.lua... it's a guiframe consisting of other guis.
-- this function should be called when the user begins dragging on a window
controller.beginWindowDrag = function(window, dontDock)
controller.undockWindow(window)
local offset = window.absolutePosition - engine.input.mousePosition
local startAlpha = window.backgroundAlpha
local startZ = window.zIndex
window.zIndex = 99
window.backgroundAlpha = startAlpha*0.5;
local helpers
if not dontDock then
helpers = controller.renderDockLocationHelpers()
end
local selectedPosition = window.position
local selectedSize = window.size
while engine.input:isMouseButtonDown(enums.mouseButton.left) do
local newpos = engine.input.mousePosition + offset
window.position = guiCoord(0, newpos.x, 0, newpos.y)
if not dontDock then
if engine.input.mousePosition.y >= engine.input.screenSize.y * 0.75 and
engine.input.mousePosition.x < engine.input.screenSize.x * 0.75 then
helpers.outline.size = guiCoord(1/(#controller.bottomDock+1), 0, 0.2, 0)
helpers.outline.position = guiCoord(luaHelpers.roundToMultiple(engine.input.mousePosition.x/engine.input.screenSize.x, 1/(#controller.bottomDock+1)), 0, 0.8, 0)
helpers.outline.visible = true
elseif engine.input.mousePosition.x >= engine.input.screenSize.x * 0.75 then
helpers.outline.size = guiCoord(0.2, 0, 1/(#controller.rightDock+1), 0)
helpers.outline.position = guiCoord(0.8, 0, luaHelpers.roundToMultiple(engine.input.mousePosition.y/engine.input.screenSize.y, 1/(#controller.rightDock+1)), 0)
helpers.outline.visible = true
else
helpers.outline.visible = false
end
end
wait()
end
local start = os.clock()
if not dontDock then
helpers:destroy()
if engine.input.mousePosition.y >= engine.input.screenSize.y * 0.75 and
engine.input.mousePosition.x < engine.input.screenSize.x * 0.75 then
controller.dockWindow(window, controller.bottomDock, luaHelpers.roundToMultiple(engine.input.mousePosition.x/engine.input.screenSize.x, 1/(#controller.bottomDock+1)))
elseif engine.input.mousePosition.x >= engine.input.screenSize.x * 0.75 then
controller.dockWindow(window, controller.rightDock, luaHelpers.roundToMultiple(engine.input.mousePosition.y/engine.input.screenSize.y, 1/(#controller.rightDock+1)))
end
end
window.backgroundAlpha = startAlpha
window.zIndex = startZ
lastUpdate = os.clock()
saveDocks()
end
return controller

View File

@ -1,102 +0,0 @@
-- Copyright (c) 2019 teverse.com
-- environment.lua
local environmentController = {}
local firstRun = true
local toolsController = require("tevgit:create/controllers/tool.lua")
--[[
local physicsButton = toolsController.createButton("testingTab", "fa:s-pause", "Pause")
physicsButton:mouseLeftReleased(function ()
if engine.physics.running then
engine.physics:pause()
else
engine.physics:resume()
end
end)
]]
--[[
engine.physics:changed(function (p,v)
if p == "running" then
if v then
physicsButton.image.texture = "fa:s-pause"
physicsButton.text.text = "Pause"
else
physicsButton.image.texture = "fa:s-play"
physicsButton.text.text = "Resume"
end
end
end)]]
environmentController.createStarterMap = function()
print("creating starter map")
local mainLight = engine.construct("light", workspace, {
name = "mainLight",
position = vector3(3, 2, 0),
type = enums.lightType.point,
rotation = quaternion():setEuler(math.rad(-40), math.rad(25), 0),
shadows = true,
power = 2
})
local basePlate = engine.construct("block", workspace, {
name = "basePlate",
colour = colour(0.6, 0.6, 0.6),
size = vector3(100, 1, 100),
position = vector3(0, -1, 0),
workshopLocked = true
})
engine.construct("block", workspace, {
name = "redBlock",
colour = colour(1, 0, 0),
size = vector3(1, 1, 1),
position = vector3(0, 0, 0)
})
engine.construct("block", workspace, {
name = "greenBlock",
colour = colour(0, 1, 0),
size = vector3(1, 1, 1),
position = vector3(1, 0, 0),
mesh = "primitive:wedge",
rotation = quaternion:setEuler(0, math.rad(-90), 0)
})
local block = engine.construct("block", workspace, {
name = "blueBlock",
colour = colour(0, 0, 1),
size = vector3(1, 1, 1),
position = vector3(0.5, 1, 0),
mesh = "primitive:sphere"
})
--[[
-- Create a script source.
-- Noting that this API was not supposed to be used by Developers.
-- It is most likely only going to be used internally by our engine.
-- The idea is that a developer can update this script source and multiple "containers" can use one source.
local scriptSource = engine.construct("scriptSource", engine.assets.lua.shared, {
name = "main",
source = "print('test')"
})
-- Create a script container, this container is responsible for executing code referenced from a script source.
-- Each container is treat as its own script and gets its own sandbox.
local scriptRunner = engine.construct("scriptContainer", engine.workspace, {name = "mainRunner"})
scriptRunner.source = scriptSource -- autoruns if autorun is true (defaults to true)
]]
end
environmentController.setDefault = function()
engine.graphics.clearColour = colour:fromRGB(56,56,66)
engine.graphics.ambientColour = colour:fromRGB(235, 235, 235)
end
return environmentController

View File

@ -1,238 +0,0 @@
local controller = {}
local uiController = require("tevgit:create/controllers/ui.lua")
local themeController = require("tevgit:create/controllers/theme.lua")
local dockController = require("tevgit:create/controllers/dock.lua")
local selectionController = require("tevgit:create/controllers/select.lua")
local propertyEditor = require("tevgit:create/controllers/propertyEditor.lua")
local contextMenu = require("tevgit:create/controllers/contextMenu.lua")
local luaFolderContextOptions = {
["new scriptSource"] = {
action = function ()
if #selectionController.selection == 1 then
local folder = selectionController.selection[1]
if folder:isA("luaSharedFolder") or folder:isA("luaServerFolder") or folder:isA("luaClientFolder") then
local newSource = engine.scriptSource()
newSource.parent = folder
newSource.name = "newScriptSource"
end
end
end
}
}
local overridingIcons = {
scriptSource = "fa:s-file-code",
scriptContainer = "fa:s-microchip",
input = {"fa:s-keyboard", "fa:r-keyboard"},
debug = "fa:s-bug",
light = "fa:s-lightbulb",
block = "fa:s-cube",
camera = "fa:s-camera"
}
--dictionary of buttons to their corrosponding objects.
local buttonToObject = {}
local function updatePositions(frame)
local y = 10
if not frame then
frame = controller.scrollView
else
y = 20
end
if frame.children then
for _,v in pairs(frame.children) do
if v.name ~= "icon" then
v.position = guiCoord(0, 10, 0, y)
y = y + updatePositions(v)
end
end
end
if type(frame) == "guiTextBox" then
local regularIconWithChildren = "fa:s-folder"
local regularIconWithOutChildren = "fa:r-folder"
local expandedIcon = "fa:s-folder-open"
local icons = overridingIcons[buttonToObject[frame].className]
if icons then
if type(icons) == "string" then
regularIconWithChildren = icons
regularIconWithOutChildren = icons
else
regularIconWithChildren = icons[1]
regularIconWithOutChildren = icons[1]
expandedIcon = icons[2]
end
end
if y == 20 then
-- no children
if buttonToObject[frame] and buttonToObject[frame].children and #buttonToObject[frame].children > 0 then
--object has children but is not expanded
frame.icon.texture = regularIconWithChildren
frame.icon.imageAlpha = 1
frame.textAlpha = 1
frame.fontFile = "OpenSans-SemiBold.ttf"
else
--object has no children
frame.icon.texture = regularIconWithOutChildren
frame.icon.imageAlpha = .2
frame.textAlpha = .6
frame.fontFile = "OpenSans-Regular.ttf"
end
else
-- object is expanded
frame.textAlpha = 0.6
frame.fontFile = "OpenSans-Regular.ttf"
frame.icon.imageAlpha = 0.4
frame.icon.texture = expandedIcon
end
if buttonToObject[frame] and selectionController.isSelected(buttonToObject[frame]) then
frame.backgroundAlpha = 0.3
else
frame.backgroundAlpha = 0
end
end
return y
end
controller.updatePositions = updatePositions
local function createHierarchyButton(object, guiParent)
local btn = uiController.create("guiTextBox", guiParent, {
text = " " .. object.name, --ik...
size = guiCoord(1, -6, 0, 18),
fontSize = 16,
cropChildren = false,
backgroundAlpha = 0,
hoverCursor = "fa:s-hand-pointer"
}, "main")
buttonToObject[btn] = object
local icon = uiController.create("guiImage", btn, {
name = "icon",
texture = "fa:s-folder",
position = guiCoord(0, 1, 0, 1),
size = guiCoord(0, 16, 0, 16),
handleEvents = false,
backgroundAlpha = 0
})
local expanded = false
local lastClick = 0
btn:onSync("mouseRightPressed", function()
if (object:isA("folder")) then
selectionController.setSelection(object.children)
propertyEditor.generateProperties(object)
else
selectionController.setSelection({object})
end
controller.scrollView.canvasSize = guiCoord(1, 0, 0, updatePositions())
end)
btn:mouseLeftReleased(function()
if os.time() - lastClick < 0.35 then
lastClick = 0
--expand
expanded = not expanded
if expanded then
for _,child in pairs(object.children) do
createHierarchyButton(child, btn)
end
controller.scrollView.canvasSize = guiCoord(1, 0, 0, updatePositions())
if object.className == "scriptSource" or object.className == "scriptContainer" then
require("tevgit:create/controllers/scriptController.lua").editScript(object)
end
else
for _,v in pairs(btn.children) do
if v.name ~= "icon" then
if buttonToObject[v] then
buttonToObject[v] = nil
end
v:destroy()
end
end
controller.scrollView.canvasSize = guiCoord(1, 0, 0, updatePositions())
end
else
--single click
local currentTime = os.time()
lastClick = currentTime
if (object:isA("folder")) then
selectionController.setSelection(object.children)
propertyEditor.generateProperties(object)
else
selectionController.setSelection({object})
end
controller.scrollView.canvasSize = guiCoord(1, 0, 0, updatePositions())
end
end)
local childAddedEvent = object:on("childAdded", function (child)
if expanded then
createHierarchyButton(child, btn)
end
controller.scrollView.canvasSize = guiCoord(1, 0, 0, updatePositions())
end)
local childRemovedEvent = object:onSync("childRemoved", function (child)
if expanded then
for button,obj in pairs(buttonToObject) do
if obj == child and button.alive then
button:destroy()
end
end
end
controller.scrollView.canvasSize = guiCoord(1, 0, 0, updatePositions())
end)
btn:once("destroying", function ()
childAddedEvent:disconnect()
end)
if object:isA("luaSharedFolder") or object:isA("luaServerFolder") or object:isA("luaClientFolder") then
contextMenu.bind(btn, luaFolderContextOptions)
else
selectionController.applyContext(btn)
end
return btn
end
function controller.createUI(workshop)
controller.window = uiController.createWindow(workshop.interface,
guiCoord(1, -300, 1, -400), -- pos
guiCoord(0, 250, 0, 400), -- size
"Hierarchy")
controller.window.visible = true
dockController.dockWindow(controller.window, dockController.rightDock)
controller.scrollView = uiController.create("guiScrollView", controller.window.content, {
name = "scrollview",
size = guiCoord(1, 0, 1, 0)
}, "mainTopBar")
local toolsController = require("tevgit:create/controllers/tool.lua")
local hierarchyBtn = toolsController.createButton("windowsTab", "fa:s-sitemap", "Hierarchy")
hierarchyBtn:mouseLeftReleased(function ()
controller.window.visible = not controller.window.visible
end)
createHierarchyButton(engine, controller.scrollView)
controller.scrollView.canvasSize = guiCoord(1, 0, 0, updatePositions())
end
return controller

View File

@ -1,205 +0,0 @@
--[[
Copyright 2019 Teverse
@File history.lua
@Author(s) Neztore
--]]
-- Manages undo/redo points. A stack type thing so we don't guzzle memory.
-- Config
local undoSize = 50
local redoSize = 20
-- Lists are stack like, but they fill up to 50 and then return to the start and just overwrite previous points.
local pointer = 0
local undoList = {}
local redoPointer = 0
local redoList = {}
local workshop
function getWorkshop (ws)
workshop = ws
end
-- TODO: Add support for combined actions (i.e. move multiple items at once)
-- TODO: Add buttons
-- TODO: Improve stability
-- HISTORY_CREATED, HISTORY_DELETED: When something is created or deleted the prop will be set to one of these.
-- These are named this way to make sure they'll never collide will real props (they never will: underscores are evil - jay)
-- We only store what is changed
function addUndo (object, changedProp, value)
if changedProp == "HISTORY_DELETED" then
-- Copy properties
if object.alive and object.parent and object.parent.alive then
local toStore = cloneObject(object)
undoList[pointer] = {
className = object.className,
prop = changedProp,
value = toStore
}
else
return print("Can't add destroyed object to history")
end
else
undoList[pointer] = {
obj = object,
prop = changedProp,
value = value
}
end
if pointer >= undoSize then
-- We return to start and start overwriting.
pointer = 0
else
pointer = pointer + 1
end
end
-- Restores the last point on the list
function restorePoint ()
if pointer == 0 then
if undoList[undoSize] then
-- The last item exists, so we just go to back. We go to 1+ to account for pointer problems.
pointer = undoSize + 1
end
end
local point = undoList[pointer - 1]
if point then
if point.prop == "HISTORY_CREATED" then
print("removing created")
-- To undo it we delete it. We should also copy the properties in-case it was a copy.
local toStore = cloneObject(point.obj)
local parent = point.obj.parent
addRedo(point.obj.className, "HISTORY_CREATED", toStore)
point.obj:destroy()
elseif point.prop == "HISTORY_DELETED" then
local parent = point.value.parent
if parent then
local object = engine.construct(point.className, parent, point.value)
addRedo(object, "HISTORY_DELETED")
else
print("Failed to undo deletion: Parent no longer exists.")
end
else
print("undoing "..point.prop)
-- Normal: it hasn't been deleted.
if point.obj and point.obj.alive then
local object = point.obj
-- not destroyed; reset value to prev & take redo value
local redoValue = object[point.prop]
addRedo(object, point.prop, redoValue)
-- Restore value
object[point.prop] = point.value
end
end
local object = point.obj
undoList[pointer - 1] = nil
pointer = pointer - 1
else
print("Nothing left to undo!")
end
end
-- "Redoes" the last action.
function addRedo (object, changedProp, value)
redoList[redoPointer] = {
obj = object,
prop = changedProp,
value = value
}
if redoPointer >= redoSize then
-- We return to start and start overwriting.
redoPointer = 0
else
redoPointer = redoPointer + 1
end
end
-- Opposite of restorePoint
function redoAction ()
if redoPointer == 0 then
if redoList[redoSize] then
-- The last item exists, so we just go to back. We go to 1+ to account for pointer problems.
redoPointer = redoSize + 1
end
end
local point = redoList[redoPointer - 1]
if point then
if point.prop == "HISTORY_CREATED" then
-- To redo it we create it. We should have the properties
local object = engine.construct(point.obj, point.value.parent, point.value)
addUndo(object, "HISTORY_CREATED")
elseif point.prop == "HISTORY_DELETED" then
if not point.obj then print("ERROR: Object does not exist.")
addUndo(point.obj, "HISTORY_DELETED")
point.obj:destroy()
else
local object = point.obj
if object and object.alive then
-- not destroyed; reset value to prev & take redo value
local redoValue = object[point.prop]
addUndo(object, point.prop, redoValue)
-- Restore value
object[point.prop] = point.value
end
end
end
redoList[redoPointer - 1] = nil
redoPointer = redoPointer - 1
-- We return so buttons etc. know if it's empty.
return true
else
print("Nothing left to redo!")
return false
end
end
function cloneObject (object)
local members = workshop:getMembersOfObject( object )
local toStore = {}
for _, prop in pairs(members) do
local val = object[prop.property]
local pType = type(val)
if prop.writable and pType ~= "function" then
-- We can save it and re-construct it
toStore[prop.property] = val
end
end
toStore["parent"] = object.parent
return toStore
end
return {
addPoint = addUndo,
undo = restorePoint,
redo = redoAction,
giveWorkshop = getWorkshop
}

View File

@ -1,74 +0,0 @@
-- Copyright (c) 2019 teverse.com
-- select.lua
local hotkeysController = {
bindings = {}
}
local history = require("tevgit:create/controllers/history.lua")
function hotkeysController:bind(hotkeyData)
if (hotkeyData.priorKey) then
if (not self.bindings[hotkeyData.priorKey]) then
self.bindings[hotkeyData.priorKey] = {}
end
if (self.bindings[hotkeyData.priorKey][hotkeyData.key]) then
error("Hot key " .. hotkeyData.name .. " can not overwrite existing hotkey: " .. self.bindings[hotkeyData.priorKey][hotkeyData.key].name)
end
self.bindings[hotkeyData.priorKey][hotkeyData.key] = hotkeyData
else
if (self.bindings[hotkeyData.key]) then
error("Hot key " .. hotkeyData.name .. " can not overwrite existing hotkey: " .. self.bindings[hotkeyData.key].name)
end
self.bindings[hotkeyData.key] = hotkeyData
end
return hotkeyData.action
end
function hotkeysController:handle(inputObject)
for key, data in pairs(self.bindings) do
if (not data.action) then
if (engine.input:isKeyDown(key)) then
for key, data in pairs(data) do
if (inputObject.key == key) then
data.action()
return
end
end
end
else
if (inputObject.key == key) then
data.action()
return
end
end
end
end
engine.input:keyPressed(function(inputObject)
if (inputObject.systemHandled) then
return
else
hotkeysController:handle(inputObject)
end
end)
-- @hotkeys Undo/redo so we don't need to require hotkeys in history.lua
hotkeysController:bind({
name = "undo",
priorKey = enums.key.leftCtrl,
key = enums.key.z,
action = history.undo
})
hotkeysController:bind({
name = "redo",
priorKey = enums.key.leftCtrl,
key = enums.key.y,
action = history.redo
})
return hotkeysController

View File

@ -1,87 +0,0 @@
-- Teverse doesn't render anything where lights are...
-- This script should render a visible mesh in position of lights to allow the user to see/select them in 3D space.
local controller = {}
controller.lights = {}
controller.registerLight = function(light)
assert(type(light) == "light")
for _,v in pairs(controller.lights) do
if v == light then
error("already registered")
end
end
local newBlock = engine.construct("block", workspace, {
doNotSerialise=true,
name = "_CreateMode_Light_Placeholder",
size = vector3(0.3, 0.3, 0.3),
mesh = "tevurl:3d/light.glb",
emissiveColour = light.diffuseColour*20,
castsShadows =false,
position = light.position,
rotation = light.rotation
})
local destroyed = false
controller.lights[newBlock] = light
light:destroying(function ()
if not destroyed then
destroyed = true
controller.lights[newBlock] = nil
newBlock:destroy()
end
end)
--delay updates to block to lower risk of loop
local lastUpdate = nil
light:changed(function (k,v)
if not lastUpdate and newBlock[k] then
lastUpdate = os.time()
repeat wait(.1) until os.time() - lastUpdate > 0.6
newBlock.emissiveColour = (light.diffuseColour * 20):max(colour(0.1,0.1,0.1))
if newBlock.position ~= light.position then
newBlock.position = light.position
elseif newBlock.rotation ~= light.rotation then
newBlock.rotation = light.rotation
end
lastUpdate = nil
elseif lastUpdate then
lastUpdate = os.time()
end
end)
newBlock:changed(function (k,v)
if k == "position" and light.position ~= v then
light.position = v
elseif k == "rotation" and light.rotation ~= v then
light.rotation = v
end
end)
newBlock:destroying(function ()
if not destroyed then
destroyed = true
light:destroy()
end
end)
end
local function handleChild(c)
if type(c) == "light" then
print("Registering new light", c)
controller.registerLight(c)
end
end
workspace:childAdded(handleChild)
for _,v in pairs(workspace.children) do
handleChild(v)
end
return controller

View File

@ -1,929 +0,0 @@
local controller = {}
local uiController = require("tevgit:create/controllers/ui.lua")
local themeController = require("tevgit:create/controllers/theme.lua")
local colourPickerController = require("tevgit:create/extras/colourPicker.lua")
local dockController = require("tevgit:create/controllers/dock.lua")
local meshShorcuts = {
cube = "primitive:cube",
sphere = "primitive:sphere",
cylinder = "primitive:cylinder",
torus = "primitive:torus",
cone = "primitive:cone",
wedge = "primitive:wedge",
corner = "primitive:corner",
worker = "tevurl:3d/worker.glb",
duck = "tevurl:3d/Duck.glb",
avocado = "tevurl:3d/Avocado.glb",
}
controller.window = nil
controller.workshop = nil
controller.scrollView = nil
controller.excludePropertyList = {}
controller.colourPicker = nil
function controller.createUI(workshop)
controller.workshop = workshop
controller.colourPicker = colourPickerController.create()
controller.colourPicker.window.visible = false
controller.window = uiController.createWindow(workshop.interface, guiCoord(1, -300, 1, -400), guiCoord(0, 250, 0, 400), "Properties")
controller.window.visible = true
dockController.dockWindow(controller.window, dockController.rightDock)
controller.scrollView = uiController.create("guiScrollView", controller.window.content, {
name = "scrollview",
size = guiCoord(1,0,1,-32),
position = guiCoord(0,0,0,32)
}, "mainTopBar")
controller.info = uiController.create("guiTextBox", controller.window.content, {
name = "info",
size = guiCoord(1,-6,0,32),
position = guiCoord(0,3,0,0),
fontSize = 16,
textAlpha = 0.5,
text = "Nothing selected."
}, "mainTopBar")
local toolsController = require("tevgit:create/controllers/tool.lua")
local propertiesBtn = toolsController.createButton("windowsTab", "fa:s-sliders-h", "Properties")
propertiesBtn:mouseLeftReleased(function ()
controller.window.visible = not controller.window.visible
end)
end
local instanceEditing = nil
local function callbackInput(property, value)
if instanceEditing and instanceEditing[property] ~= nil then
instanceEditing[property] = value
end
end
controller.parseInputs = {
block = function (property, gui)
end,
boolean = function (property, gui)
callbackInput(property, gui.input.selected == true)
end,
number = function (property, gui)
local num = tonumber(gui.input.text)
if num then
callbackInput(property, num)
end
end,
string = function (property, gui)
callbackInput(property, gui.input.text)
end,
vector3 = function(property, gui)
local x,y,z = tonumber(gui.x.text),tonumber(gui.y.text),tonumber(gui.z.text)
if x and y and z then
callbackInput(property, vector3(x,y,z))
end
end,
vector2 = function(property, gui)
local x,y = tonumber(gui.x.text),tonumber(gui.y.text)
if x and y then
callbackInput(property, vector2(x,y))
end
end,
colour = function(property, gui)
local r,g,b = tonumber(gui.r.text),tonumber(gui.g.text),tonumber(gui.b.text)
if r and g and b then
callbackInput(property, colour(r,g,b))
end
end,
quaternion = function(property, gui)
--local x,y,z,w = tonumber(gui.x.text),tonumber(gui.y.text),tonumber(gui.z.text),tonumber(gui.w.text)
local x,y,z = tonumber(gui.x.text),tonumber(gui.y.text),tonumber(gui.z.text)
if x and y and z then
callbackInput(property, quaternion():setEuler(math.rad(x),math.rad(y),math.rad(z)))
end
end,
guiCoord = function(property, gui)
local sx,ox,sy,oy = tonumber(gui.scaleX.text),tonumber(gui.offsetX.text),tonumber(gui.scaleY.text),tonumber(gui.offsetY.text)
if sx and ox and sy and oy then
callbackInput(property, guiCoord(sx,ox,sy,oy))
end
end,
}
-- these methods are responsible for setting the propertie gui values when updated
controller.updateHandlers = {
block = function (instance, gui, value)
end,
boolean = function (instance, gui, value)
gui.input.selected = value
gui.input.text = gui.input.selected and "X" or " " -- temporary
end,
number = function (instance, gui, value)
gui.input.text = tostring(value)
end,
string = function (instance, gui, value)
gui.input.text = value
end,
vector3 = function(instance, gui, value)
gui.x.text = string.format("%.3f", value.x)
gui.y.text = string.format("%.3f", value.y)
gui.z.text = string.format("%.3f", value.z)
end,
vector2 = function(instance, gui, value)
gui.x.text = string.format("%.3f", value.x)
gui.y.text = string.format("%.3f", value.y)
end,
colour = function(instance, gui, value)
gui.r.text = string.format("%.5f", value.r)
gui.g.text = string.format("%.5f", value.g)
gui.b.text = string.format("%.5f", value.b)
gui.col.backgroundColour = value
end,
quaternion = function(instance, gui, value)
local euler = value:getEuler()
gui.x.text = string.format("%.3f", math.deg(euler.x))
gui.y.text = string.format("%.3f", math.deg(euler.y))
gui.z.text = string.format("%.3f", math.deg(euler.z))
--gui.w.text = tostring(value.w)
end,
guiCoord = function(instance, gui, value)
gui.scaleX.text = tostring(value.scaleX)
gui.offsetX.text = tostring(value.offsetX)
gui.scaleY.text = tostring(value.scaleY)
gui.offsetY.text = tostring(value.offsetY)
end,
}
controller.createInput = {
default = function(instance, property, value)
return uiController.create("guiFrame", nil, {
backgroundAlpha = 0.25,
name = "inputContainer",
size = guiCoord(0.5, 0, 0, 20),
position = guiCoord(0.5,0,0,0),
cropChildren = false
}, "secondary")
end,
block = function(instance, property, value)
local container = controller.createInput.default(value, pType, readOnly)
local x = uiController.create("guiTextBox", container, {
backgroundAlpha = 0.25,
readOnly = true,
fontSize = 18,
name = "input",
size = guiCoord(1, -4, 1, -2),
position = guiCoord(0, 2, 0, 1),
text = "Instance Selector",
align = enums.align.middle
}, "primary")
return container
end,
boolean = function(instance, property, value)
local container = controller.createInput.default(value, pType, readOnly)
local x = uiController.create("guiButton", container, {
name = "input",
size = guiCoord(0, 18, 1, -2),
position = guiCoord(0, 2, 0, 1),
text = "",
backgroundAlpha = 0.75,
align = enums.align.middle
}, "light")
x:mouseLeftReleased(function ()
x.selected = not x.selected
x.text = x.selected and "X" or " " -- temporary
controller.parseInputs[type(value)](property, container)
end)
return container
end,
number = function(instance, property, value)
local container = controller.createInput.default(value, pType, readOnly)
local x = uiController.create("guiTextBox", container, {
backgroundAlpha = 0.25,
readOnly = false,
multiline = false,
fontSize = 18,
name = "input",
size = guiCoord(1, -4, 0, 18),
position = guiCoord(0, 2, 0, 1),
text = "0",
align = enums.align.middle
}, "primary")
x:textInput(function ()
controller.parseInputs[type(value)](property, container)
end)
if property == "type" and type(instance) == "light" then
container.zIndex = 30 -- important because child elements need to be rendered above other properties!
container.size = container.size + guiCoord(0,0,0,20)
local presetSelect = uiController.create("guiTextBox", container, {
size = guiCoord(1, -4, 0, 16),
position = guiCoord(0, 2, 0, 23),
borderRadius = 3,
text = "Light Options",
fontSize = 16,
align = enums.align.middle,
backgroundAlpha = 0.75
}, "primary")
local optionsModal = uiController.create("guiFrame", container, {
position = guiCoord(-0.8, 7, 0, 48),
borderRadius = 6,
visible = false,
zIndex = 40,
borderWidth = 1,
cropChildren = false
}, "main")
local isFocused = false
local pendingHide = false
local function queueCloseModal()
if not pendingHide and optionsModal.visible then
pendingHide = true
wait(.4)
if not isFocused then
--still unfocused, lets hide.
optionsModal.visible = false
end
pendingHide=false
end
end
presetSelect:mouseFocused(function ()
optionsModal.visible = true
isFocused = true
end)
optionsModal:mouseFocused(function ()
isFocused = true
end)
presetSelect:mouseUnfocused(function ()
isFocused = false
queueCloseModal()
end)
optionsModal:mouseUnfocused(function ()
isFocused = false
queueCloseModal()
end)
uiController.create("guiImage", optionsModal, {
size = guiCoord(0, 24, 0, 24),
position = guiCoord(0.75, -12, 0, -15),
handleEvents=false,
zIndex = 10,
backgroundAlpha = 0,
texture = "fa:s-caret-up",
imageColour = optionsModal.backgroundColour
})
local curY = 0
local curX = 0
for lightType, num in pairs(enums.lightType) do
local btn = uiController.create("guiTextBox", optionsModal, {
size = guiCoord(.5, -10, 0, 18),
position = guiCoord(curX, 5, 0, curY + 4),
borderRadius = 3,
text = lightType,
fontSize = 16,
align = enums.align.middle
}, "primary")
btn:mouseFocused(function ()
isFocused = true
end)
btn:mouseUnfocused(function ()
isFocused = false
queueCloseModal()
end)
btn:mouseLeftReleased(function ()
x.text = tostring(num)
controller.parseInputs[type(value)](property, container)
end)
if curX == 0.5 then
curY = curY + 24
curX = 0
else
curX = 0.5
end
end
if curX == 0.5 then
curY = curY + 24
end
optionsModal.size = guiCoord(1.8, -10, 0, curY+4)
end
return container
end,
scriptSource = function(instance, property, value)
local container = controller.createInput.default(value, pType, readOnly)
local presetSelect = uiController.create("guiTextBox", container, {
size = guiCoord(1, -4, 0, 16),
position = guiCoord(0, 2, 0, 2),
borderRadius = 3,
text = "Edit Source",
fontSize = 16,
align = enums.align.middle,
backgroundAlpha = 0.75
}, "primary")
presetSelect:mouseLeftReleased(function ()
if instance[property] then
instance[property]:editExternal()
end
end)
return container
end,
string = function(instance, property, value)
local container = controller.createInput.default(value, pType, readOnly)
local x = uiController.create("guiTextBox", container, {
backgroundAlpha = 0.25,
readOnly = false,
multiline = false,
fontSize = 18,
name = "input",
size = guiCoord(1, -4, 0, 18),
position = guiCoord(0, 2, 0, 1),
text = "text input",
align = enums.align.middleLeft,
zIndex = 2
}, "primary")
x:textInput(function ()
controller.parseInputs[type(value)](property, container)
end)
-- TODO TODO TODO TODO
-- We need some sort of helper function that'll make
-- modals for situations like this:
if property == "mesh" then
container.zIndex = 30 -- important because child elements need to be rendered above other properties!
container.size = container.size + guiCoord(0,0,0,20)
local presetSelect = uiController.create("guiTextBox", container, {
size = guiCoord(1, -4, 0, 16),
position = guiCoord(0, 2, 0, 23),
borderRadius = 3,
text = "Mesh Presets",
fontSize = 16,
align = enums.align.middle,
backgroundAlpha = 0.75
}, "primary")
local meshModal = uiController.create("guiFrame", container, {
position = guiCoord(-0.8, 7, 0, 48),
borderRadius = 6,
visible = false,
zIndex = 40,
borderWidth = 1,
cropChildren = false
}, "main")
local isFocused = false
local pendingHide = false
local function queueCloseModal()
if not pendingHide and meshModal.visible then
pendingHide = true
spawnThread(function ()
-- Code here...
wait(.4)
if not isFocused then
--still unfocused, lets hide.
meshModal.visible = false
end
pendingHide=false
end)
end
end
presetSelect:onSync("mouseFocused", function ()
meshModal.visible = true
isFocused = true
end)
meshModal:onSync("mouseFocused", function ()
isFocused = true
end)
presetSelect:onSync("mouseUnfocused", function ()
isFocused = false
queueCloseModal()
end)
meshModal:onSync("mouseUnfocused", function ()
isFocused = false
queueCloseModal()
end)
uiController.create("guiImage", meshModal, {
size = guiCoord(0, 24, 0, 24),
position = guiCoord(0.75, -12, 0, -15),
handleEvents=false,
zIndex = 10,
backgroundAlpha = 0,
texture = "fa:s-caret-up",
imageColour = meshModal.backgroundColour
})
local curY = 0
local curX = 0
for meshName, actualMeshName in pairs(meshShorcuts) do
local btn = uiController.create("guiTextBox", meshModal, {
size = guiCoord(.5, -10, 0, 18),
position = guiCoord(curX, 5, 0, curY + 4),
borderRadius = 3,
text = meshName,
fontSize = 16,
align = enums.align.middle
}, "primary")
btn:onSync("mouseFocused", function ()
isFocused = true
end)
btn:onSync("mouseUnfocused", function ()
isFocused = false
queueCloseModal()
end)
btn:mouseLeftReleased(function ()
x.text = actualMeshName
controller.parseInputs[type(value)](property, container)
end)
if curX == 0.5 then
curY = curY + 24
curX = 0
else
curX = 0.5
end
end
if curX == 0.5 then
curY = curY + 24
end
meshModal.size = guiCoord(1.8, -10, 0, curY+4)
end
return container
end,
vector3 = function(instance, property, value)
local container = controller.createInput.default(value, pType, readOnly)
container.size = guiCoord(container.size.scaleX, 0, 0, 60)
local xLabel = uiController.create("guiTextBox", container, {
name = "labelX",
size = guiCoord(0, 10, 1/3, -1),
position = guiCoord(0,-10,0,1),
fontSize = 16,
textAlpha = 0.6,
text = "X",
align = enums.align.topLeft
}, "mainText")
local x = uiController.create("guiTextBox", container, {
backgroundAlpha = 0.25,
readOnly = false,
multiline = false,
fontSize = 18,
name = "x",
size = guiCoord(1, -4, 1/3, -1),
position = guiCoord(0, 2, 0, 0),
text = "0",
align = enums.align.middle
}, "primary")
local yLabel = xLabel:clone()
yLabel.name = "yLabel"
yLabel.text = "Y"
yLabel.parent = container
yLabel.position = guiCoord(0, -10, 1/3, 1)
themeController.add(yLabel, "mainText")
local y = x:clone()
y.name = "y"
y.parent = container
y.position = guiCoord(0, 2, 1/3, 0)
themeController.add(y, "primary")
local zLabel = xLabel:clone()
zLabel.name = "zLabel"
zLabel.text = "Z"
zLabel.parent = container
zLabel.position = guiCoord(0, -10, 2/3, 1)
themeController.add(yLabel, "mainText")
local z = x:clone()
z.name = "z"
z.parent = container
z.position = guiCoord(0, 2, 2/3, 0)
themeController.add(z, "primary")
local function handler()
controller.parseInputs[type(value)](property, container)
end
x:textInput(handler)
y:textInput(handler)
z:textInput(handler)
return container
end,
vector2 = function(instance, property, value)
local container = controller.createInput.default(value, pType, readOnly)
container.size = guiCoord(container.size.scaleX, 0, 0, 40)
local xLabel = uiController.create("guiTextBox", container, {
name = "labelX",
size = guiCoord(0, 10, 1/2, -1),
position = guiCoord(0,-10,0,2),
fontSize = 16,
textAlpha = 0.6,
text = "X",
align = enums.align.topLeft
}, "mainText")
local x = uiController.create("guiTextBox", container, {
backgroundAlpha = 0.25,
readOnly = false,
multiline = false,
fontSize = 18,
name = "x",
size = guiCoord(0, -4, 1/2, -2),
position = guiCoord(0, 2, 0, 1),
text = "0",
align = enums.align.middle
}, "primary")
local yLabel = xLabel:clone()
yLabel.name = "yLabel"
yLabel.text = "Y"
yLabel.parent = container
yLabel.position = guiCoord(0, -10, 1/2, 2)
themeController.add(yLabel, "mainText")
local y = x:clone()
y.name = "y"
y.parent = container
y.position = guiCoord(0, 2, 1/2, 1)
themeController.add(y, "primary")
local function handler()
controller.parseInputs[type(value)](property, container)
end
x:textInput(handler)
y:textInput(handler)
return container
end,
quaternion = function(instance, property, value)
-- maybe quaternions need an Euler editor?
local container = controller.createInput.default(value, pType, readOnly)
container.size = guiCoord(container.size.scaleX, 0, 0, 60)
local xLabel = uiController.create("guiTextBox", container, {
name = "labelX",
size = guiCoord(0, 12, 1/3, -1),
position = guiCoord(0,-10,0,1),
fontSize = 16,
textAlpha = 0.6,
text = "X",
align = enums.align.topLeft
}, "mainText")
local x = uiController.create("guiTextBox", container, {
backgroundAlpha = 0.25,
readOnly = false,
multiline = false,
fontSize = 18,
name = "x",
size = guiCoord(1, -4, 1/3, -1),
position = guiCoord(0, 2, 0, 0),
text = "0",
align = enums.align.middle
}, "primary")
local yLabel = xLabel:clone()
yLabel.name = "yLabel"
yLabel.text = "Y"
yLabel.parent = container
yLabel.position = guiCoord(0, -10, 1/3, 1)
themeController.add(yLabel, "mainText")
local y = x:clone()
y.name = "y"
y.parent = container
y.position = guiCoord(0, 2, 1/3, 0)
themeController.add(y, "primary")
local zLabel = xLabel:clone()
zLabel.name = "zLabel"
zLabel.text = "Z"
zLabel.parent = container
zLabel.position = guiCoord(0, -10, 2/3, 1)
themeController.add(zLabel, "mainText")
local z = x:clone()
z.name = "z"
z.parent = container
z.position = guiCoord(0, 2, 2/3, 0)
themeController.add(z, "primary")
--[[local wLabel = xLabel:clone()
wLabel.name = "wLabel"
wLabel.text = "W"
wLabel.parent = container
wLabel.position = guiCoord(0, -12, 3/4, 2)
themeController.add(wLabel, "mainText")
local w = x:clone()
w.name = "w"
w.parent = container
w.position = guiCoord(0, 2, 3/4, 1)
themeController.add(w, "primary")]]
local function handler()
controller.parseInputs[type(value)](property, container)
end
x:textInput(handler)
y:textInput(handler)
z:textInput(handler)
--w:textInput(handler)
return container
end,
guiCoord = function(instance, property, value)
local container = controller.createInput.default(value, pType, readOnly)
local x = uiController.create("guiTextBox", container, {
backgroundAlpha = 0.25,
readOnly = false,
multiline = false,
fontSize = 18,
name = "scaleX",
size = guiCoord(1/4, -4, 1, -2),
position = guiCoord(0, 2, 0, 1),
text = "0",
align = enums.align.middle
}, "primary")
local y = x:clone()
y.name = "offsetX"
y.parent = container
y.position = guiCoord(1/4, 2, 0, 1)
themeController.add(y, "primary")
local z = x:clone()
z.name = "scaleY"
z.parent = container
z.position = guiCoord(1/2, 2, 0, 1)
themeController.add(z, "primary")
local w = x:clone()
w.name = "offsetY"
w.parent = container
w.position = guiCoord(3/4, 2, 0, 1)
themeController.add(w, "primary")
local function handler()
controller.parseInputs[type(value)](property, container)
end
x:textInput(handler)
y:textInput(handler)
z:textInput(handler)
w:textInput(handler)
return container
end,
colour = function(instance, property, value)
local container = controller.createInput.default(value, pType, readOnly)
container.size = guiCoord(container.size.scaleX, 0, 0, 60)
local rLabel = uiController.create("guiTextBox", container, {
name = "labelR",
size = guiCoord(0, 10, 1/3, -1),
position = guiCoord(0,-10,0,2),
fontSize = 16,
textAlpha = 0.6,
text = "R",
align = enums.align.topLeft
}, "mainText")
local x = uiController.create("guiTextBox", container, {
backgroundAlpha = 0.25,
readOnly = false,
multiline = false,
fontSize = 18,
name = "r",
size = guiCoord(1, -24, 1/3, -2),
position = guiCoord(0, 2, 0, 1),
text = "1",
align = enums.align.middle
}, "primary")
local gLabel = rLabel:clone()
gLabel.name = "gLabel"
gLabel.text = "G"
gLabel.parent = container
gLabel.position = guiCoord(0, -10, 1/3, 1)
themeController.add(gLabel, "mainText")
local g = x:clone()
g.name = "g"
g.parent = container
g.position = guiCoord(0, 2, 1/3, 1)
themeController.add(g, "primary")
local bLabel = rLabel:clone()
bLabel.name = "bLabel"
bLabel.text = "B"
bLabel.parent = container
bLabel.position = guiCoord(0, -10, 2/3, 1)
themeController.add(bLabel, "mainText")
local b = x:clone()
b.name = "b"
b.parent = container
b.position = guiCoord(0, 2, 2/3, 1)
themeController.add(b, "primary")
local function handler()
controller.parseInputs[type(value)](property, container)
end
x:textInput(handler)
g:textInput(handler)
b:textInput(handler)
local col = engine.construct("guiFrame", container, {
name = "col",
size = guiCoord(0, 14, 1, -2),
position = guiCoord(1, -18, 0, 1),
backgroundColour = colour(1,1,1),
borderRadius = 2,
})
col:mouseLeftReleased(function ()
controller.colourPicker.window.visible = not controller.colourPicker.window.visible
if controller.colourPicker.window.visible and instanceEditing and instanceEditing[property] then
controller.colourPicker.setColour(instanceEditing[property])
controller.colourPicker.setCallback(function (c)
x.text = tostring(c.r)
g.text = tostring(c.g)
b.text = tostring(c.b)
controller.parseInputs[type(value)](property, container)
end)
end
end)
return container
end,
}
local function alphabeticalSorter(a, b)
return a.property < b.property
end
controller.eventHandlers = {}
controller.instanceEditing = nil
function controller.generateProperties(instance)
if instanceEditing == instance then return end
instanceEditing = nil
controller.instanceEditing = nil
for i,v in pairs(controller.eventHandlers) do
v:disconnect()
end
controller.eventHandlers = {}
--controller.scrollView:destroyAllChildren()
if instance then
instanceEditing = instance
controller.instanceEditing = instance
local members = controller.workshop:getMembersOfObject( instance )
table.sort( members, alphabeticalSorter )
-- prototype teverse gui system isn't perfect,
-- reuse already created instances to save time.
for _,v in pairs(controller.scrollView.children) do
v.visible = false
end
local y = 10
local propertiesCount = 0
for i, v in pairs(members) do
local value = instance[v.property]
local pType = type(value)
local readOnly = not v.writable
--letting the user turn physics off would cause raycasts to die.
if not readOnly and pType ~= "function" and v.property ~= "physics" and v.property ~= "doNotSerialise" and not controller.excludePropertyList[v.property] then
propertiesCount = propertiesCount + 1
local container = controller.scrollView["_" .. v.property .. pType]
if not container then
container = engine.construct("guiFrame", controller.scrollView,
{
name = "_" .. v.property .. pType,
backgroundAlpha = 0,
size = guiCoord(1, -10, 0, 20),
cropChildren = false
})
label = uiController.create("guiTextBox", container, {
name = "label",
size = guiCoord(0.5, -15, 1, 0),
position = guiCoord(0,0,0,0),
fontSize = 18,
text = v.property,
align = enums.align.topRight
}, "mainText")
local inputGui = nil
if controller.createInput[pType] then
inputGui = controller.createInput[pType](instance, v.property, value)
else
inputGui = controller.createInput.default(instance, v.property, value)
end
container.size = guiCoord(1, -10, 0, inputGui.size.offsetY)
container.zIndex = inputGui.zIndex
inputGui.parent = container
else
container.visible = true
end
if controller.updateHandlers[pType] then
controller.updateHandlers[pType](instance, container.inputContainer, value)
end
container.position = guiCoord(0,5,0,y)
y = y + container.size.offsetY + 3
end
end
controller.info.text = type(instance) .. " has " .. tostring(propertiesCount) .. " visible members."
table.insert( controller.eventHandlers, instance:changed(function(prop, val)
if controller.updateHandlers[type(val)] then
local container = controller.scrollView["_" .. prop]
if container then
controller.updateHandlers[type(val)](instance, container.inputContainer, val)
end
end
end))
local newSize = guiCoord(0,0,0,y)
if newSize ~= controller.scrollView.canvasSize then
controller.scrollView.viewOffset = vector2(0,0)
end
controller.scrollView.canvasSize = newSize
else
controller.info.text = "Nothing selected."
end
end
return controller

View File

@ -1,159 +0,0 @@
local controller = {}
local ui = require("tevgit:create/controllers/ui.lua")
local selectionController = require("tevgit:create/controllers/select.lua")
-- displays a dialogue to user when they want to make a new container, asks them if they want to use an existing source or not.
controller.newScriptDialogue = function(parent)
if not parent or not parent.className then return end
local backdrop = ui.create("guiFrame", ui.workshop.interface, {
size = guiCoord(1, 0, 1, 0),
backgroundAlpha = 0,
zIndex = 2000
}, "main")
engine.tween:begin(backdrop, 0.3, {backgroundAlpha = 0.7}, "inOutQuad")
local window = ui.create("guiFrame", backdrop, {
size = guiCoord(0, 450, 0, 220),
position = guiCoord(0.5, -225, 0.5, -110),
backgroundAlpha = 0.5,
borderRadius = 4
}, "light")
engine.tween:begin(window, 0.3, {
size = guiCoord(0, 400, 0, 174),
position = guiCoord(0.5, -200, 0.5, -87),
backgroundAlpha = 0.7,
}, "inOutQuad")
local title = ui.create("guiTextBox", window, {
size = guiCoord(1, -10, 0, 40),
position = guiCoord(0, 5, 0, 10),
text = "Choose a source for your new scriptContainer\nunder " .. (parent and parent.name or "?"),
fontSize = 20,
fontFile = "OpenSans-Bold.ttf",
align = enums.align.middle,
backgroundAlpha = 0
}, "light")
local existingSource = engine.construct("guiFrame", window, {
size = guiCoord(1/3, -4, 1, -56),
position = guiCoord(0, 2, 0, 46),
backgroundAlpha = 0
})
ui.create("guiImage", existingSource, {
size = guiCoord(0, 50, 0, 50),
position = guiCoord(0.5, -25, 0.5, -25),
backgroundAlpha = 0,
texture = "fa:s-search",
handleEvents = false
}, "light")
ui.create("guiTextBox", existingSource, {
size = guiCoord(1, -10, 0, 32),
position = guiCoord(0, 5, 0.5, 25),
backgroundAlpha = 0,
fontSize = 16,
text = "Existing\nSource {TODO!!!}",
align = enums.align.topMiddle,
handleEvents = false
}, "light")
local newServer = engine.construct("guiFrame", window, {
size = guiCoord(1/3, -4, 1, -56),
position = guiCoord(1/3, 2, 0, 46),
backgroundAlpha = 0
})
ui.create("guiImage", newServer, {
size = guiCoord(0, 50, 0, 50),
position = guiCoord(0.5, -25, 0.5, -25),
backgroundAlpha = 0,
texture = "fa:s-server",
handleEvents = false
}, "light")
ui.create("guiTextBox", newServer, {
size = guiCoord(1, -10, 0, 32),
position = guiCoord(0, 5, 0.5, 25),
backgroundAlpha = 0,
fontSize = 16,
text = "New Server\nSource",
align = enums.align.topMiddle,
handleEvents = false
}, "light")
local newClient = engine.construct("guiFrame", window, {
size = guiCoord(1/3, -4, 1, -56),
position = guiCoord(2/3, 2, 0, 46),
backgroundAlpha = 0
})
ui.create("guiImage", newClient, {
size = guiCoord(0, 50, 0, 50),
position = guiCoord(0.5, -25, 0.5, -25),
backgroundAlpha = 0,
texture = "fa:s-laptop-code",
handleEvents = false
}, "light")
ui.create("guiTextBox", newClient, {
size = guiCoord(1, -10, 0, 32),
position = guiCoord(0, 5, 0.5, 25),
backgroundAlpha = 0,
fontSize = 16,
text = "New Client\nSource",
align = enums.align.topMiddle,
handleEvents = false
}, "light")
local keyListener = engine.input:keyPressed(function (inputObj)
if inputObj.key == enums.key.escape then
backdrop:destroy()
end
end)
backdrop:once("mouseLeftPressed", function ()
backdrop:destroy()
end)
backdrop:once("destroying", function ()
keyListener:disconnect()
end)
newClient:once("mouseLeftPressed", function ()
local name = "newClientScript"
local newSource = engine.construct("scriptSource", engine.assets.lua.client, {name = name.."Source"})
local newScript = engine.construct("scriptContainer", parent, {name = name.."Container"})
newScript.scriptType = enums.scriptType.client
newScript.source = newSource
selectionController.setSelection({newScript})
wait(.4)
backdrop:destroy()
end)
newServer:once("mouseLeftPressed", function ()
local name = "newServerScript"
local newSource = engine.construct("scriptSource", engine.assets.lua.server, {name = name.."Source"})
local newScript = engine.construct("scriptContainer", parent, {name = name.."Container"})
newScript.scriptType = enums.scriptType.server
newScript.source = newSource
selectionController.setSelection({newScript})
wait(.4)
backdrop:destroy()
end)
end
controller.editScript = function (obj)
-- Code here...
if type(obj) == "scriptSource" then
obj:editExternal()
elseif obj.source then
print(container)
obj.source:editExternal()
end
end
return controller

View File

@ -1,460 +0,0 @@
-- Copyright (c) 2019 teverse.com
-- select.lua
local selectionController = {
selectable = true,
clipboard = {},
selection = {},
boundingBoxListeners = {},
boundingBox = engine.construct("block", nil, {
name = "_CreateMode_boundingBox",
wireframe = true,
castsShadows = false,
static = true,
physics = false,
colour = colour(1, 0.8, 0.8),
opacity = 0,
size = vector3(0, 0, 0),
doNotSerialise = true
})
}
local hotkeys = require("tevgit:create/controllers/hotkeys.lua")
local contextMenu = require("tevgit:create/controllers/contextMenu.lua")
local propertyEditor = require("tevgit:create/controllers/propertyEditor.lua")
local lights = require("tevgit:create/controllers/lights.lua")
local helpers = require("tevgit:create/helpers.lua")
local history = require("tevgit:create/controllers/history.lua")
local isCalculating = false
local function clearSelectedObjectsInClipboard()
for _, object in pairs(selectionController.selection) do
for index, object2 in pairs(selectionController.clipboard) do
if (object == object2) then
selectionController.clipboard[index] = nil
end
end
end
end
function selectionController.copySelection()
selectionController.clipboard = selectionController.selection
end
function selectionController.pasteSelection(keepPosition)
local selection = {}
local clipboard = selectionController.clipboard
local size, pos = selectionController.calculateBounding(clipboard)
for _, object in pairs(clipboard) do
if (object) then
if (not helpers.startsWith(object.name, "_CreateMode_")) then
history.addPoint(object, "HISTORY_CREATED")
object.emissiveColour = colour()
local clone = object:clone()
clone.parent = workspace
if (not keepPosition) then
clone.position = object.position + vector3(0, size.y, 0)
end
table.insert(selection, clone)
elseif (lights.lights[object]) then
local light = lights.lights[object]
history.addPoint(light, "HISTORY_CREATED")
local clone = light:clone()
clone.shadows = false
clone.parent = workspace
if (not keepPosition) then
clone.position = light.position + vector3(0,1,0)
else
clone.position = light.position
end
end
end
end
selectionController.setSelection(selection)
print("Pasted selection", selection)
--[[for _,v in pairs(hotkeysController.clipboard) do
if v and v.name ~= "_CreateMode_Light_Placeholder" then
history.addPoint(v, "HISTORY_CREATED")
v.emissiveColour = colour(0,0,0)
local new = v:clone()
new.parent = workspace
new.position = v.position + vector3(0,size.y,0)
table.insert(newItems, new)
elseif v then
--copying a light
local light = require("tevgit:create/controllers/lights.lua").lights[v]
if light then
history.addPoint(light, "HISTORY_CREATED")
local new = light:clone()
new.shadows = false -- purely a performance boost.
new.parent = workspace
new.position = light.position + vector3(0,1,0)
-- table.insert(newItems, new)
end
end
end
selectionController.setSelection(newItems)]]
end
function selectionController.deleteSelection()
local objects = selectionController.selection
clearSelectedObjectsInClipboard()
selectionController.setSelection({})
if(objects[1].parent:isA("folder")) then
history.addPoint(objects[1].parent, "HISTORY_DELETED")
objects[1].parent:destroy()
else
for _, object in pairs(objects) do
if (object) then
history.addPoint(object, "HISTORY_DELETED")
object:destroy()
end
end
end
end
function selectionController.duplicateSelection()
selectionController.copySelection()
selectionController.pasteSelection(true)
end
function selectionController.deselectSelection()
selectionController.setSelection({})
end
function selectionController.groupSelection()
if (#selectionController.selection > 1) then
local selection = selectionController.selection
local folder = engine.folder("group")
folder.parent = workspace
for _, object in pairs(selection) do object.parent = folder end
propertyEditor.generateProperties(folder)
end
end
function selectionController.ungroupSelection()
if (#selectionController.selection > 1) then
local parent = selectionController.selection[1].parent
if (parent:isA("folder")) then
for _, object in pairs(parent.children) do object.parent = parent.parent end
propertyEditor.generateProperties(selectionController.selection[1])
parent:destroy()
end
end
end
function selectionController.removeBoundingListener(block)
for i,v in pairs(selectionController.boundingBoxListeners) do
if v[1] == block then
selectionController.boundingBoxListeners[i] = nil
return nil
end
end
end
function selectionController.addBoundingListener(block)
table.insert(selectionController.boundingBoxListeners, { block, block:changed(selectionController.calculateBoundingBox) })
end
function selectionController.calculateBounding(items)
local min, max;
for _,v in pairs(items) do
if type(v) == "block" then
if v and v.alive then
if not min then min = v.position; max=v.position end
local vertices = helpers.calculateVertices(v)
for i,v in pairs(vertices) do
min = min:min(v)
max = max:max(v)
end
end
end
end
if max ~= nil and min ~= nil then
return (max-min), (max - (max-min)/2)
end
end
function selectionController.calculateBoundingBox()
if isCalculating then return end
isCalculating = true
if #selectionController.selection < 1 then
selectionController.boundingBox.size = vector3(0,0,0)
selectionController.boundingBox.opacity = 0
isCalculating = false
return
end
selectionController.boundingBox.opacity = 0.5
local size, pos = selectionController.calculateBounding(selectionController.selection)
if size and pos then
selectionController.boundingBox.size = size
selectionController.boundingBox.position = pos
end
--engine.tween:begin(boundingBox, .025, {size = max-min, position = max - (max-min)/2}, "inQuad")
isCalculating = false
end
function selectionController.setSelection(selection)
for _,v in pairs(selectionController.selection) do
if type(v) == "block" then
v.emissiveColour = colour(0.0, 0.0, 0.0)
end
end
for _,v in pairs(selectionController.boundingBoxListeners) do
v[2]:disconnect()
end
selectionController.boundingBoxListeners = {}
selectionController.selection = {}
for _,v in pairs(selection) do
if type(v) == "block" then
v.emissiveColour = colour(0.025, 0.025, 0.15)
selectionController.addBoundingListener(v)
end
table.insert(selectionController.selection, v)
end
if (#selection > 0) then
propertyEditor.generateProperties(selection[1])
end
selectionController.calculateBoundingBox()
end
function selectionController.isSelected(object)
for _,v in pairs(selectionController.selection) do
if v == object then
return true
end
end
end
engine.input:mouseLeftReleased(function(input)
if not input.systemHandled and selectionController.selectable then
local mouseHit = engine.physics:rayTestScreen(engine.input.mousePosition)
if not mouseHit or mouseHit.object.workshopLocked then
if mouseHit and mouseHit.object.name == "_CreateMode_" then return end -- dont deselect
-- User clicked empty space, deselect everything??#
for _,v in pairs(selectionController.selection) do
if type(v) == "block" then
if v and v.alive then
v.emissiveColour = colour(0.0, 0.0, 0.0)
else
print("Cannot change emissiveColour: Object deleted.")
end
end
end
selectionController.selection = {}
for _,v in pairs(selectionController.boundingBoxListeners) do
v[2]:disconnect()
end
selectionController.boundingBoxListeners = {}
selectionController.calculateBoundingBox()
return
end
local doSelect = true
if not engine.input:isKeyDown(enums.key.leftShift) then
-- deselect everything that's already selected and move on
for _,v in pairs(selectionController.selection) do
if type(v) == "block" then
v.emissiveColour = colour(0.0, 0.0, 0.0)
end
end
selectionController.selection = {}
for _,v in pairs(selectionController.boundingBoxListeners) do
v[2]:disconnect()
end
selectionController.boundingBoxListeners = {}
selectionController.calculateBoundingBox()
else
for i,v in pairs(selectionController.selection) do
if v == mouseHit.object then
table.remove(selectionController.selection, i)
selectionController.removeBoundingListener(v)
v.emissiveColour = colour(0.0, 0.0, 0.0)
doSelect = false
end
end
end
if doSelect then
if (mouseHit.object.parent:isA("folder")) then
selectionController.setSelection(mouseHit.object.parent.children)
propertyEditor.generateProperties(mouseHit.object.parent)
else
if type(mouseHit.object) == "block" and mouseHit.object.name ~= "_CreateMode_Light_Placeholder" then
mouseHit.object.emissiveColour = colour(0.025, 0.025, 0.15)
end
table.insert(selectionController.selection, mouseHit.object)
selectionController.addBoundingListener(mouseHit.object)
selectionController.calculateBoundingBox()
if mouseHit and mouseHit.object.name == "_CreateMode_Light_Placeholder" then
if lights.lights[mouseHit.object] then
--ignore the block they pressed, they clicked a light
propertyEditor.generateProperties(lights.lights[mouseHit.object])
return
end
end
propertyEditor.generateProperties(mouseHit.object)
end
end
end
end)
-- @hotkeys Copy, paste, & duplicate
hotkeys:bind({ name = "copy", priorKey = enums.key.leftCtrl, key = enums.key.c, action =selectionController.copySelection })
hotkeys:bind({ name = "paste", priorKey = enums.key.leftCtrl, key = enums.key.v, action =selectionController.pasteSelection })
hotkeys:bind({ name = "duplicate", priorKey = enums.key.leftCtrl, key = enums.key.d, action =selectionController.duplicateSelection })
-- @hotkeys Delete, deselect, group & TBA ungroup
hotkeys:bind({ name = "delete", key = enums.key.delete, action =selectionController.deleteSelection })
hotkeys:bind({ name = "deselect", key = enums.key.escape, action = selectionController.deselectSelection })
hotkeys:bind({ name = "group", priorKey = enums.key.leftCtrl, key = enums.key.g, action =selectionController.groupSelection })
-- @hotkey Focus selection
local function focusSelection()
if (#selectionController.selection > 0) then
local mdn = vector3(helpers.median(selectionController.selection, "x"), helpers.median(selectionController.selection, "y"), helpers.median(selectionController.selection, "z") )
engine.tween:begin(workspace.camera, .2, { position = mdn + (workspace.camera.rotation * vector3(0,0,1) * 15) }, "outQuad")
end
end
hotkeys:bind({
name = "focus on selection",
key = enums.key.f,
action = focusSelection
})
-- @hotkey Select all
hotkeys:bind({
name = "select all",
priorKey = enums.key.leftCtrl,
key = enums.key.a,
action = function()
local selection = {}
for _,v in pairs(workspace.children) do
if not v.workshopLocked and type(v) == "block" then
table.insert(selection, v)
end
end
selectionController.setSelection(selection)
end
})
-- @section Context Menu
local function newBlockWrapper(mesh)
return function()
local mousePos = engine.input.mousePosition
local mouseHit = engine.physics:rayTestScreen(contextMenu.contextLastOpenedAt or mousePos)
local block = engine.construct("block", workspace, {
position = mouseHit.hitPosition,
mesh = mesh
})
end
end
local function newScript()
return require("tevgit:create/controllers/scriptController.lua").newScriptDialogue(selectionController.selection[1])
end
function selectionController.getContextOptions()
local options = {
new = {
subOptions = {
block = {
action = newBlockWrapper()
},
sphere = {
action = newBlockWrapper("primitive:sphere")
},
wedge = {
action = newBlockWrapper("primitive:wedge")
},
script = {
action = newScript
}
}
}
}
if (#selectionController.selection > 0) then
options.copy = {
hotkey = "ctrl + c",
action = selectionController.copySelection
}
options.delete = {
hotkey = "del",
action = selectionController.deleteSelection
}
options.focus = {
hotkey = "f",
action = focusSelection
}
if (#selectionController.selection > 1) then
if (selectionController.selection[1].parent:isA("folder")) then
options.ungroup = {
action = selectionController.ungroupSelection
}
else
options.group = {
hotkey = "ctrl + g",
action = selectionController.groupSelection
}
end
end
end
if (#selectionController.clipboard > 0) then
options.paste = {
hotkey = "ctrl + v",
action = selectionController.pasteSelection
}
options.duplicate = {
hotkey = "ctrl + d",
action = selectionController.duplicateSelection
}
end
return options
end
function selectionController.applyContext(object)
--getContextOptions will be ran whenever we display a context menu for t his obj.
return contextMenu.bind(object, selectionController.getContextOptions)
end
engine.input:mouseRightPressed(function(input)
wait(0.10)
if ((not input.systemHandled) and (engine.physics:rayTestScreen(engine.input.mousePosition)) and (not engine.input:isMouseButtonDown(enums.mouseButton.right))) then
contextMenu.display(contextMenu.create(selectionController.getContextOptions()))
end
end)
return selectionController

View File

@ -1,59 +0,0 @@
local toolsController = require("tevgit:create/controllers/tool.lua")
local selectionController = require("tevgit:create/controllers/select.lua")
local propertyController = require("tevgit:create/controllers/propertyEditor.lua")
local ui = require("tevgit:create/controllers/ui.lua")
local remoteTest = toolsController.createButton("topBar", "fa:s-globe", "Test")
local db = false
remoteTest:mouseLeftReleased(function ()
if db then return end
db = true
local backdrop = ui.create("guiFrame", ui.workshop.interface, {
size = guiCoord(1, 0, 1, 0),
backgroundAlpha = 0,
zIndex = 2000
}, "main")
engine.tween:begin(backdrop, 0.3, {backgroundAlpha = 0.7}, "inOutQuad")
local window = ui.create("guiFrame", backdrop, {
size = guiCoord(0, 450, 0, 60),
position = guiCoord(0.5, -225, 0.5, -30),
backgroundAlpha = 0.5,
borderRadius = 4
}, "light")
engine.tween:begin(window, 0.3, {
size = guiCoord(0, 400, 0, 40),
position = guiCoord(0.5, -200, 0.5, -20),
backgroundAlpha = 0.7,
}, "inOutQuad")
local title = ui.create("guiTextBox", window, {
size = guiCoord(1, -10, 1, -10),
position = guiCoord(0, 5, 0, 5),
text = "Launching remote server...",
fontSize = 20,
fontFile = "OpenSans-Bold.ttf",
align = enums.align.middle,
backgroundAlpha = 0
}, "light")
local loaded = false
spawnThread(function ()
wait(5)
if not loaded and title and title.alive then
title.text = "This is taking a little longer than usual..."
end
end)
local success = ui.workshop:remoteTestServer(enums.serverLocation.london)
loaded = true
if not success then
title.text = "Something went wrong?"
wait(1)
end
db = false
end)

View File

@ -1,138 +0,0 @@
-- Copyright (c) 2019 teverse.com
-- theme.lua
local themeController = {}
print ("DEBUG: Loading theme.lua")
-- values from default are used in all styles unless overridden.
-- theme names are probably gonna have to get made meaningful...
themeController.darkTheme = {
default = {
fontFile = "OpenSans-Regular.ttf",
backgroundColour = colour:fromRGB(66, 66, 76),
borderColour = colour:fromRGB(56, 56, 66),
textColour = colour:fromRGB(255, 255, 255)
},
main = {
backgroundColour = colour:fromRGB(66, 66, 76),
textColour = colour:fromRGB(255, 255, 255),
},
mainText = {
backgroundAlpha = 0, -- background
textColour = colour:fromRGB(255, 255, 255),
},
mainTopBar = {
backgroundColour = colour:fromRGB(45, 45, 55),
textColour = colour:fromRGB(255, 255, 255),
borderColour = colour:fromRGB(15, 15, 25)
},
secondary = {
backgroundColour = colour:fromRGB(55, 55, 66),
textColour = colour:fromRGB(255, 255, 255)
},
primary = {
backgroundColour = colour:fromRGB(78, 83, 91),
textColour = colour:fromRGB(255,255,255)
},
primaryText = {
backgroundAlpha = 0,
textColour = colour:fromRGB(255,255,255)
},
secondaryText = {
backgroundAlpha = 0,
textColour = colour:fromRGB(255, 255, 255),
textAlpha = .5
},
light = {
backgroundColour = colour:fromRGB(255,255,255),
textColour = colour:fromRGB(66, 66, 76),
imageColour = colour:fromRGB(66, 66, 76),
borderColour = colour:fromRGB(245,245,245),
},
tools = {
selected = colour:fromRGB(66, 134, 244),
hovered = colour(0.9, 0.9, 0.9),
deselected = colour(0.6, 0.6, 0.6)
}
}
themeController.lightTheme = {
default = {
fontFile = "OpenSans-Regular.ttf",
backgroundColour = colour:fromRGB(189, 195, 199),
textColour = colour:fromRGB(0,0,0)
},
main = {
backgroundColour = colour:fromRGB(189, 195, 199),
textColour = colour:fromRGB(0,0,0),
},
mainText = {
backgroundAlpha = 0,
textColour = colour:fromRGB(0,0,0),
},
mainTopBar = {
backgroundColour = colour:fromRGB(127, 140, 141),
textColour = colour:fromRGB(0,0,0),
},
secondary = {
backgroundColour = colour:fromRGB(149, 165, 166),
textColour = colour:fromRGB(0,0,0)
},
primary = {
backgroundColour = colour:fromRGB(52, 73, 94),
textColour = colour:fromRGB(255,255,255)
},
light = {
backgroundColour = colour:fromRGB(44, 62, 80),
textColour = colour:fromRGB(255,255,255),
},
tools = {
selected = colour:fromRGB(66, 134, 244),
hovered = colour(0.9, 0.9, 0.9),
deselected = colour(0.6, 0.6, 0.6)
}
}
themeController.currentTheme = themeController.darkTheme
themeController.guis = {} --make this a weak metatable (keys)
themeController.set = function(theme)
themeController.currentTheme = theme
for gui, style in pairs(themeController.guis) do
themeController.applyTheme(gui)
end
end
themeController.applyTheme = function(gui)
local styleName = themeController.guis[gui]
local style = themeController.currentTheme[styleName]
if not style then
style = {}
end
if themeController.currentTheme["default"] then
for property, value in pairs(themeController.currentTheme["default"]) do
if not style[property] and gui[property] and gui[property] ~= value then --Chosen style does not have this property
gui[property] = value
end
end
end
for property, value in pairs(style) do
if gui[property] and gui[property] ~= value then
gui[property] = value
end
end
end
themeController.add = function(gui, style)
--if themeController.guis[gui] then return end
themeController.guis[gui] = style
themeController.applyTheme(gui)
end
return themeController

View File

@ -1,63 +0,0 @@
local controller = {}
local uiController = require("tevgit:create/controllers/ui.lua")
local themeController = require("tevgit:create/controllers/theme.lua")
controller.window = nil
controller.workshop = nil
controller.scrollView = nil
function controller.createUI(workshop)
controller.workshop = workshop
controller.window = uiController.createWindow(workshop.interface, guiCoord(1, -400, 1, -50), guiCoord(0, 80, 0, 50), "Theme")
controller.window.visible = false
local toolsController = require("tevgit:create/controllers/tool.lua")
local themeSwitcherButton = toolsController.createButton("windowsTab", "fa:s-swatchbook", "Themes")
themeSwitcherButton:mouseLeftReleased(function ()
controller.window.visible = not controller.window.visible
end)
local darkBtn = engine.construct("guiFrame", controller.window.content, {
name = "input",
size = guiCoord(0, 20, 0, 20),
position = guiCoord(0, 5, 0, 5),
text = "",
backgroundAlpha = 0.75,
backgroundColour = colour:fromRGB(66, 66, 76)
})
local lightBtn = engine.construct("guiFrame", controller.window.content, {
name = "input",
size = guiCoord(0, 20, 0, 20),
position = guiCoord(0, 30, 0, 5),
text = "",
backgroundAlpha = 0.75,
backgroundColour = colour:fromRGB(200,200,200)
})
local moreBtn = engine.construct("guiTextBox", controller.window.content, {
name = "input",
size = guiCoord(0, 20, 0, 20),
position = guiCoord(0, 55, 0, 5),
text = "+",
backgroundAlpha = 0.75,
backgroundColour = colour(1, 1, 1),
textColour = colour(0, 0, 0),
align = enums.align.middle
})
darkBtn:mouseLeftReleased(function()
themeController.set(themeController.darkTheme)
end)
lightBtn:mouseLeftReleased(function()
themeController.set(themeController.lightTheme)
end)
moreBtn:mouseLeftReleased(function()
print("Open main theme chooser!")
end)
end
return controller

View File

@ -1,195 +0,0 @@
--[[
Copyright 2019 Teverse
@File tool.lua
@Author(s) Jay, Ly
@Updated 5/8/19
--]]
TOOL_BUTTON_SIZE = guiCoord(0, 30, 0, 30)
TOOL_BUTTON_DEFAULT_POSITION = guiCoord(0, 8, 0, 8)
TOOL_BUTTON_OFFSET = 45
local toolsController = {
currentToolId = 0,
tools = {},
ui = nil,
workshop = nil,
container = nil
}
-- Not sure if the following should be in this controller... Oh well.
toolsController.menus = {}
-- You must create the gui before calling this function
-- This function simply registers the menu to this controller.
function toolsController.registerMenu(name, gui)
if toolsController.menus[name] then
return error("Menu already exists", 2)
end
toolsController.menus[name] = {gui = gui, buttons = {}, currentX = 5, currentY = 0}
return true
end
-- Each button would be able to have their own size, and it is this controller's
-- responsibility to position them properly.
function toolsController.registerButton(name, gui)
if not toolsController.menus[name] then
return error("Menu doesn't exist", 2)
end
table.insert(toolsController.menus[name], {gui=gui})
local menu = toolsController.menus[name]
gui.parent = menu.gui
gui.position = guiCoord(0, menu.currentX, 0, menu.currentY)
local guiSize = gui.absoluteSize
if menu.currentY + guiSize.y >= menu.gui.absoluteSize.y then
menu.currentY = 0
menu.currentX = menu.currentX + guiSize.x + 5
else
menu.currentY = menu.currentY + guiSize.y
end
end
-- Creates a button with an image and a label and registers it.
-- height should be a decimal.
function toolsController.createButton(menuName, image, label, height)
if not height then height = 1 end
local menu = toolsController.menus[menuName]
local gui = toolsController.ui.createFrame(menu.gui, {size=guiCoord(0,55,height,0), hoverCursor = "fa:s-hand-pointer"}, "mainTopBar")
if image then
local imgSize = math.min(50, menu.gui.absoluteSize.y) - 5
local img = toolsController.ui.create("guiImage", gui, {name = "image", size=guiCoord(0, (2/3) * imgSize, 0, (2/3) * imgSize), position=guiCoord(0.5, -((1/3) * imgSize),0,5), texture=image, handleEvents=false}, "mainTopBar")
end
local txt = toolsController.ui.create("guiTextBox", gui, {name = "text", size=guiCoord(1, 0, image and 1/3 or 1, -5), position=guiCoord(0,0,image and 2/3 or 0,0), text=label, fontSize=15, align=enums.align.middle, handleEvents=false}, "mainTopBar")
toolsController.registerButton(menuName, gui)
return gui
end
local themeController = require("tevgit:create/controllers/theme.lua")
local function onToolButtonMouseLeftReleased(toolId)
--[[
@Description
Manages toggling tools when a button is clicked
@Params
Integer, toolId
The unique # of the tool
]]
if (toolsController.currentToolId > 0) then
-- @Note Deactive current tool in use
local currentTool = toolsController.tools[toolsController.currentToolId]
print("Debug: Deactivating tool " .. currentTool.name)
currentTool.button.imageColour = themeController.currentTheme.tools.deselected
currentTool.deactivated(currentTool.id)
end
if toolsController.currentToolId == toolId then
-- @Note Deselects tool {toolId}
print("Debug: Deselecting tools")
toolsController.currentToolId = 0
else
-- @Note Selects tool {toolId}
toolsController.currentToolId = toolId
local currentTool = toolsController.tools[toolsController.currentToolId]
print("Debug: Activating tool " .. currentTool.name)
currentTool.button.imageColour = themeController.currentTheme.tools.selected
currentTool.activated(currentTool.id)
end
end
function toolsController:register(tool)
--[[
@Description
Registers a tool into the controller
@Params
Dictionary, tool
The given information about a {tool} including its functions
@Model {
name = String,
icon = String,
description = String,
data = [Dictionary],
activated = Function,
deactivated = Functon,
}
@Returns
Integer, toolId
The resultant unique # of the tools that was registered
]]
local toolId = #self.tools + 1
local toolButton = self.ui.create(
"guiImage",
self.container,
{
hoverCursor = "fa:s-hand-pointer",
size = TOOL_BUTTON_SIZE,
position = TOOL_BUTTON_DEFAULT_POSITION + guiCoord(0, 0, 0, TOOL_BUTTON_OFFSET * #self.tools),
imageColour = themeController.currentTheme.tools.deselected,
texture = tool.icon,
backgroundAlpha = 0,
},
"main"
)
if tool.hotKey then
engine.input:keyPressed(function(inputObj)
if inputObj.systemHandled then return end
if inputObj.key == tool.hotKey then
onToolButtonMouseLeftReleased(toolId)
end
end)
end
toolButton:mouseLeftReleased(function()
onToolButtonMouseLeftReleased(toolId)
end)
self.tools[toolId] = {
id = toolId,
name = tool.name,
button = toolButton,
hotKey = tool.hotKey,
data = tool.data and tool.data or {},
activated = tool.activated,
deactivated = tool.deactivated
}
local containerSize = self.container.size
containerSize.scaleY = 0
containerSize.offsetY = TOOL_BUTTON_OFFSET * #self.tools
self.container.size = containerSize
return toolId
end
return toolsController

View File

@ -1,103 +0,0 @@
--the purpose of this script is to unify all the tools
--by allowing each one to access the same common settings
--set by the user
local controller = {}
local uiController = require("tevgit:create/controllers/ui.lua")
local themeController = require("tevgit:create/controllers/theme.lua")
controller.gridStep = 0.2
controller.rotateStep = math.rad(9)
controller.axis = {{"x", true},{"y", true},{"z", true}} -- should grid step be on .. axis
controller.window = nil
controller.workshop = nil
function controller.createUI(workshop)
controller.workshop = workshop
controller.window = uiController.createWindow(workshop.interface, guiCoord(0, 66, 0, 100), guiCoord(0, 165, 0, 93), "Tool Settings")
local toolsController = require("tevgit:create/controllers/tool.lua")
local settingsBtn = toolsController.createButton("windowsTab", "fa:s-cogs", "Settings")
settingsBtn:mouseLeftReleased(function ()
controller.window.visible = not controller.window.visible
end)
local gridLabel = uiController.create("guiTextBox", controller.window.content, {
size = guiCoord(0.6,-10,0,18),
position = guiCoord(0,5,0,4),
align = enums.align.middleRight,
wrap = false,
text = "Grid Step"
}, "mainText")
local gridStepInput = uiController.create("guiTextBox", controller.window.content, {
size = guiCoord(0.4,-10,0,18),
position = guiCoord(0.6,5,0,4),
readOnly = false,
align = enums.align.middle,
borderRadius = 5,
text = tostring(controller.gridStep)
}, "main")
gridStepInput:textInput(function ()
local value = tonumber(gridStepInput.text)
if value then
controller.gridStep = value
end
end)
local x = 5
for i,v in pairs(controller.axis) do
local gridAxisLabel = uiController.create("guiTextBox", controller.window.content, {
size = guiCoord(0,20,0,18),
position = guiCoord(0,x,0,28),
borderRadius = 5,
text = v[1] .. ":"
}, "mainText")
x=x+20
local gridAxisInput = uiController.create("guiButton", controller.window.content, {
size = guiCoord(0,18,0,18),
position = guiCoord(0,x,0,28),
align = enums.align.middle,
text = v[2] and "X" or " ",
selected = v[2]
}, "main")
gridAxisInput:mouseLeftReleased(function ()
controller.axis[i][2] = not controller.axis[i][2]
gridAxisInput.selected = controller.axis[i][2]
gridAxisInput.text = gridAxisInput.selected and "X" or " "
end)
x=x+22
end
local rotateLabel = uiController.create("guiTextBox", controller.window.content, {
size = guiCoord(0.6,-10,0,18),
position = guiCoord(0,5,0,50),
align = enums.align.middleRight,
wrap = false,
text = "Rotate Step"
}, "mainText")
local rotateStepInput = uiController.create("guiTextBox", controller.window.content, {
size = guiCoord(0.4,-10,0,18),
position = guiCoord(0.6,5,0,50),
readOnly = false,
align = enums.align.middle,
borderRadius = 5,
text = tostring(math.deg(controller.rotateStep))
}, "main")
rotateStepInput:textInput(function ()
local value = math.rad(tonumber(gridStepInput.text))
if value then
controller.rotateStep = value
end
end)
end
return controller

View File

@ -1,276 +0,0 @@
-- Copyright (c) 2019 teverse.com
-- ui.lua
local uiController = {}
local themeController = require("tevgit:create/controllers/theme.lua")
local toolsController = require("tevgit:create/controllers/tool.lua")
local uiTabController = require("tevgit:create/controllers/uiTabController.lua")
uiTabController.ui = uiController
local dockController = require("tevgit:create/controllers/dock.lua")
dockController.ui = uiController
uiController.create = function(className, parent, properties, style)
if not parent then parent = uiController.workshop.interface end
local gui = engine.construct(className, parent, properties)
themeController.add(gui, style and style or "default")
return gui
end
uiController.createFrame = function(parent, properties, style)
if not parent then parent = uiController.workshop.interface end
local gui = uiController.create("guiFrame", parent, properties, style)
return gui
end
uiController.createWindow = function(parent, pos, size, title, dontDock)
if not parent then parent = uiController.workshop.interface end
local container = engine.construct("guiFrame", parent, {
name = "windowContainer",
position = pos,
size = size
})
local titleBar = uiController.create("guiFrame", container, {
name = "titleBar",
size = guiCoord(1,0,0,22),
hoverCursor = "fa:s-hand-pointer"
}, "main")
local closeButton = uiController.create("guiImage", titleBar, {
name = "Close",
texture = "fa:s-times",
position = guiCoord(1 , -20 ,0,3),
hoverCursor = "fa:s-hand-pointer",
size = guiCoord(0, 15, 0, 15),
})
closeButton:mouseLeftPressed(function ()
container.visible = false
end)
titleBar:mouseLeftPressed(function ()
dockController.beginWindowDrag(container, dontDock)
end)
local textLabel = uiController.create("guiTextBox", titleBar, {
name = "textLabel",
size = guiCoord(1,-10,1,-2),
position = guiCoord(0,5,0,0),
text = title,
handleEvents=false
}, "mainText")
uiController.createFrame(titleBar, {
name = "borderBottom",
size = guiCoord(1, 0, 0, 2),
position = guiCoord(0,0,1,-2)
}, "secondary")
local content = uiController.create("guiFrame", container, {
name = "content",
position = guiCoord(0,0,0,22),
size = guiCoord(1,0,1,-22)
}, "mainTopBar")
return container
end
local function spinCb()
if not uiController.loadingFrame.visible then
uiController.loadingTween.tweenObject.rotation = 0
uiController.loadingTween:restart()
end
end
uiController.setLoading = function(loading, message)
if not uiController.loadingFrame then return end
if loading then
uiController.loadingFrame.visible = true
uiController.loadingFrame.loadingMessage.text = message and message or "Loading"
spinCb()
else
uiController.loadingFrame.visible = false
end
end
uiController.createMainInterface = function(workshop)
uiController.workshop = workshop
uiController.loadingFrame = uiController.create("guiFrame", workshop.interface, {
name = "loadingFrame",
size = guiCoord(1,0,1,0),
position = guiCoord(0,0,0,0),
zIndex = 1000,
}, "main")
uiController.create("guiTextBox", uiController.loadingFrame, {
name = "loadingMessage",
position = guiCoord(0, 10, 0.5, 0),
size = guiCoord(1, -20, 0.5, -10),
align = enums.align.topMiddle,
fontSize = 21,
backgroundAlpha = 0,
text = "Please wait whilst Create Mode loads the latest assets."
}, "main")
local loadingImage = uiController.create("guiImage", uiController.loadingFrame, {
name = "loadingImage",
position = guiCoord(0.5, -15, .333, -15),
size = guiCoord(0, 30, 0, 30),
texture = "fa:s-cog"
}, "main")
uiController.loadingTween = engine.tween:create(loadingImage, 1, {rotation = 360}, "inOutQuad", spinCb)
local sideBar = uiController.createFrame(workshop.interface, {
name = "toolbars",
size = guiCoord(0,46,1,0),
position = guiCoord(0,10,0,100)
}, "mainTopBar")
uiController.tabs = uiController.createFrame(workshop.interface, {
name = "topbarTabs",
size = guiCoord(1, 0, 0, 23),
position = guiCoord(0,0,0,0)
}, "main")
uiController.createFrame(uiController.tabs, {
name = "borderBottom",
size = guiCoord(1, 0, 0, 2),
position = guiCoord(0,0,1,-2)
}, "secondary")
uiController.topBar = uiController.createFrame(workshop.interface, {
name = "topbar",
size = guiCoord(1, 0, 0, 60),
position = guiCoord(0,0,0,23)
}, "mainTopBar")
uiController.windowsTab = uiController.createFrame(workshop.interface, {
name = "windowsTab",
size = guiCoord(1, 0, 0, 60),
position = guiCoord(0,0,0,23)
}, "mainTopBar")
uiController.createTab = uiController.createFrame(workshop.interface, {
name = "createTab",
size = guiCoord(1, 0, 0, 60),
position = guiCoord(0,0,0,23)
}, "mainTopBar")
uiController.testingTab = uiController.createFrame(workshop.interface, {
name = "testingTab",
size = guiCoord(1, 0, 0, 60),
position = guiCoord(0,0,0,23)
}, "mainTopBar")
local tabController = uiTabController.registerTabs(uiController.tabs, "secondary", "main")
uiTabController.createTab(uiController.tabs, "File", uiController.topBar)
uiTabController.createTab(uiController.tabs, "Windows", uiController.windowsTab)
uiTabController.createTab(uiController.tabs, "Create", uiController.createTab)
uiTabController.createTab(uiController.tabs, "Testing", uiController.testingTab)
toolsController.container = sideBar
toolsController.workshop = workshop
uiController.workshop = workshop
uiController.theme = themeController
toolsController.ui = uiController
toolsController.registerMenu("windowsTab", uiController.windowsTab)
toolsController.registerMenu("createTab", uiController.createTab)
toolsController.registerMenu("testingTab", uiController.testingTab)
--[[local darkmode = true
toolsController.createButton("windowsTab", "fa:s-palette", "Switch themes"):mouseLeftReleased(function ()
darkmode = not darkmode
if not darkmode then
themeController.set(themeController.lightTheme)
else
themeController.set(themeController.darkTheme)
end
end)]]
toolsController.registerMenu("topBar", uiController.topBar)
local saveBtn = toolsController.createButton("topBar", "fa:s-file-download", "Save")
local saveAsBtn = toolsController.createButton("topBar", "fa:s-file-export", "Save As")
local openBtn = toolsController.createButton("topBar", "fa:s-folder-open", "Open")
local publishBtn = toolsController.createButton("topBar", "fa:s-cloud-upload-alt", "Publish")
publishBtn.image.backgroundAlpha = 0.45
publishBtn.text.textAlpha = 0.45
--[[
local function checkIfPublishable()
settingsBar.btn.visible = (engine.workshop.gameFilePath ~= "")
settingsBar.publishNote.text = (engine.workshop.gameFilePath == "" and "You need to save this game before publishing." or "This file isn't linked to the TevCloud.")
settingsBar.btn.label.text = (engine.workshop.gameCloudId == "" and "Publish" or "Update")
if engine.workshop.gameCloudId ~= "" then
settingsBar.publishNote.text = "This is a TevCloud project."
end
end
checkIfPublishable()
engine.workshop:changed(checkIfPublishable)
]]
saveBtn:mouseLeftReleased(function()
workshop:saveGame()
end)
saveAsBtn:mouseLeftReleased(function()
workshop:saveGameAsDialogue()
end)
openBtn:mouseLeftReleased(function()
workshop:openFileDialogue()
end)
uiController.publishStatus = uiController.createFrame(workshop.interface, {
name = "publishStatus",
size = guiCoord(0, 200, 0, 60),
position = guiCoord(0.5, -100, 0.5, -30),
borderRadius = 5,
visible = false,
}, "main")
uiController.create("guiTextBox", uiController.publishStatus, {
name = "label",
size = guiCoord(1, 0, 0, 24),
position = guiCoord(0,0,0,4),
align = enums.align.middle,
text = "Publishing..."
}, "main")
workshop:changed(function (p)
if workshop.gameFilePath ~= "" then
publishBtn.image.backgroundAlpha = 1
publishBtn.text.textAlpha = 1
else
publishBtn.image.backgroundAlpha = 0.45
publishBtn.text.textAlpha = 0.45
end
end)
workshop:published(function (success)
if success then
uiController.publishStatus.label.text = "Success! " .. workshop.gameCloudId
wait(2)
uiController.publishStatus.visible = false
else
uiController.publishStatus.label.text = "Failed"
wait(2)
uiController.publishStatus.visible = false
end
end)
publishBtn:mouseLeftReleased(function ()
uiController.publishStatus.visible = true
uiController.publishStatus.label.text = "Publishing"
workshop:publishDialogue()
end)
end
return uiController

View File

@ -1,56 +0,0 @@
local controller = {}
local themeController = require("tevgit:create/controllers/theme.lua")
controller.widgets = {}
controller.ui = nil
function controller.registerTabs(container, selectedStyle, deselectedStyle)
controller.widgets[container] = {
selected = selectedStyle,
deselected = deselectedStyle,
tabs = {},
active = true,
currentX = 10
}
end
function controller.createTab(container, name, callback)
if controller.widgets[container] then
local active = controller.widgets[container].active
controller.widgets[container].active = false
local btn = controller.ui.create("guiTextBox", container, {
name = name,
size = guiCoord(0, 50, 0, 18),
position = guiCoord(0,controller.widgets[container].currentX,0,3),
text = name,
align = enums.align.middle,
hoverCursor = "fa:s-hand-pointer",
fontSize = 18,
readOnly = true
}, active and controller.widgets[container].selected or controller.widgets[container].deselected)
controller.widgets[container].tabs[btn] = callback
local newX = math.min(130, btn.textDimensions.x + 40)
btn.size = guiCoord(0, newX, 0, 18)
controller.widgets[container].currentX = controller.widgets[container].currentX + newX + 10
if type(callback) ~= "function" and callback then
-- callback not provided, assuming this was a gui passed, and that this controller should hide/show it
callback.visible = active
btn:mouseLeftReleased(function ()
controller.setTab(container, btn)
end)
end
end
end
function controller.setTab(container, onBtn)
for btn, cb in pairs(controller.widgets[container].tabs) do
controller.widgets[container].tabs[btn].visible = (btn == onBtn)
themeController.add(btn, (btn==onBtn) and controller.widgets[container].selected or controller.widgets[container].deselected)
end
end
return controller

View File

@ -1,277 +0,0 @@
local colourPicker = {}
local uiController = require("tevgit:create/controllers/ui.lua")
local hues = {
colour(1,0,0),
colour(1,0,1),
colour(0,0,1),
colour(0,1,1),
colour(0,1,0),
colour(1,1,0),
colour(1,0,0),
}
colourPicker.create = function()
local window = uiController.createWindow(uiController.workshop.interface,
guiCoord(0.5, -150, 0.5, -90),
guiCoord(0, 300, 0, 180),
"Colour Picker",
true)
local callback = nil
local startColour = colour(1,0,0)
local currentColour = colour(1,0,0)
window.visible = true
local colourPickerGradient = engine.construct("guiFrameMultiColour", window.content, {
name = "square",
size = guiCoord(0, 150, 0, 150),
position = guiCoord(0, 5, 0, 5),
topLeftColour = colour(1,1,1),
topRightColour = startColour,
bottomLeftColour = colour(1,1,1),
bottomRightColour = startColour
})
-- To have black on the bottom we need to overlay this...
engine.construct("guiFrameMultiColour", colourPickerGradient, {
name = "overlay",
size = guiCoord(1,0,1,0),
position = guiCoord(0, 0, 0, 0),
topLeftColour = colour(0,0,0),
topLeftAlpha = 0,
topRightColour = colour(0,0,0),
topRightAlpha = 0,
bottomLeftColour = colour(0,0,0),
bottomLeftAlpha = 1,
bottomRightColour = colour(0,0,0),
bottomRightAlpha = 1,
handleEvents = false
})
local marker = engine.construct("guiFrame", colourPickerGradient, {
name = "marker",
size = guiCoord(0, 6, 0, 6),
position = guiCoord(0, 0, 0, 0),
handleEvents=false,
backgroundColour = colour(1,1,1),
borderColour = colour(0,0,0),
zIndex = 10,
borderWidth = 1,
borderRadius = 6,
borderAlpha = 1
})
local hueBar = engine.construct("guiFrame", window.content, {
name = "hueBar",
size = guiCoord(0, 30, 1, -10),
position = guiCoord(0, 160, 0, 5),
backgroundAlpha = 0
})
local hueBarMARKER = engine.construct("guiFrame", hueBar, {
name = "hueBarMARKER",
size = guiCoord(1, 0, 0, 1),
position = guiCoord(0, 0, 0, 0),
handleEvents=false,
backgroundAlpha = 0,
borderColour = colour(0,0,0),
zIndex = 10,
borderWidth = 2,
borderAlpha = 1
})
for i = 1, 6 do
local colourPickerGradient = engine.construct("guiFrameMultiColour", hueBar, {
handleEvents = false,
size = guiCoord(1, 0, 1/6, 1),
position = guiCoord(0, 0, (i-1)*(1/6), 0),
topLeftColour = hues[i],
topRightColour = hues[i],
bottomLeftColour = hues[i+1],
bottomRightColour = hues[i+1],
handleEvents = false
})
end
local rLabel = uiController.create("guiTextBox", window.content, {
name = "labelR",
size = guiCoord(0, 20, 0, 16),
position = guiCoord(0,200,0,5),
fontSize = 16,
textAlpha = 0.6,
text = "R",
align = enums.align.topLeft
}, "mainText")
local rInput = uiController.create("guiTextBox", window.content, {
backgroundAlpha = 0.25,
readOnly = false,
multiline = false,
fontSize = 18,
name = "r",
size = guiCoord(1, -230, 0,16),
position = guiCoord(0, 220, 0, 5),
text = "1",
align = enums.align.middle
}, "primary")
local gLabel = rLabel:clone()
gLabel.name = "gLabel"
gLabel.text = "G"
gLabel.parent = window.content
gLabel.position = guiCoord(0, 200, 0, 22)
--themeController.add(gLabel, "mainText")
local g = rInput:clone()
g.name = "g"
g.parent = window.content
g.position = guiCoord(0, 220, 0, 22)
-- themeController.add(g, "primary")
local bLabel = rLabel:clone()
bLabel.name = "bLabel"
bLabel.text = "B"
bLabel.parent = window.content
bLabel.position = guiCoord(0, 200, 0, 39)
--themeController.add(bLabel, "mainText")
local b = rInput:clone()
b.name = "b"
b.parent = window.content
b.position = guiCoord(0, 220, 0, 39)
local hexLabel = rLabel:clone()
hexLabel.name = "hexLabel"
hexLabel.text = "#"
hexLabel.parent = window.content
hexLabel.position = guiCoord(0, 200, 0, 55)
--themeController.add(bLabel, "mainText")
local HEX = rInput:clone()
HEX.name = "FFFFFF"
HEX.parent = window.content
HEX.position = guiCoord(0, 220, 0, 55)
-- themeController.add(b, "primary")
local function handler()
local newR = tonumber(rInput.text)
local newG = tonumber(g.text)
local newB = tonumber(b.text)
if not newR or not newG or not newB then return end
local newColour = colour(newR, newG, newB)
end
rInput:textInput(handler)
g:textInput(handler)
b:textInput(handler)
hueBar:mouseLeftPressed(function ()
while engine.input:isMouseButtonDown(enums.mouseButton.left) do
local pos = engine.input.mousePosition - hueBar.absolutePosition
local size = hueBar.absoluteSize
local y = pos.y/hueBar.absoluteSize.y
local sector = math.ceil(pos.y/(size.y * (1/6)))
local hue = hues[sector]
if hue and hues[sector+1] then
hueBarMARKER.position = guiCoord(0,0,y,0)
local selected = hue:lerp(hues[sector+1], (y - ((size.y * ((sector-1)/6))/hueBar.absoluteSize.y)) / (1/6))
startColour = selected
colourPickerGradient.topRightColour = startColour
colourPickerGradient.bottomRightColour = startColour
local x = marker.absolutePosition.x/colourPickerGradient.absoluteSize.x
local y = marker.absolutePosition.y/colourPickerGradient.absoluteSize.y
local selectedColour = startColour:lerp(colour(1,1,1), 1-x)
selectedColour = selectedColour:lerp(colour(0,0,0), y)
window.content.backgroundColour = selectedColour
rInput.text = tostring(selectedColour.r*255)
g.text = tostring(selectedColour.g*255)
b.text = tostring(selectedColour.b*255)
HEX.text = selectedColour:getHex()
if type(callback) == "function" and selectedColour ~= currentColour then
callback(selectedColour)
currentColour = selectedColour
end
end
wait()
end
end)
colourPickerGradient:mouseLeftPressed(function ()
while engine.input:isMouseButtonDown(enums.mouseButton.left) do
local pos = engine.input.mousePosition - colourPickerGradient.absolutePosition
marker.position = guiCoord(0, pos.x+2, 0, pos.y-2)
local x = pos.x/colourPickerGradient.absoluteSize.x
local y = pos.y/colourPickerGradient.absoluteSize.y
local selectedColour = startColour:lerp(colour(1,1,1), 1-x)
selectedColour = selectedColour:lerp(colour(0,0,0), y)
window.content.backgroundColour = selectedColour
rInput.text = tostring(selectedColour.r*255)
g.text = tostring(selectedColour.g*255)
b.text = tostring(selectedColour.b*255)
HEX.text = selectedColour:getHex()
if type(callback) == "function" and selectedColour ~= currentColour then
callback(selectedColour)
currentColour = selectedColour
end
wait()
end
end)
return {
window = window,
setColour = function(c)
local h,s,l = c:getHSL()
h=h*360
local marker = math.ceil(h / 60)
if marker <= 0 then marker = 1 end
local pos = hueBar.absolutePosition
local size = hueBar.absoluteSize
local hue = hues[marker]
local selected = hue:lerp(hues[marker+1], ((h - (60*(marker-1)))/60))
startColour = selected
colourPickerGradient.topRightColour = startColour
colourPickerGradient.bottomRightColour = startColour
rInput.text = tostring(c.r*255)
g.text = tostring(c.g*255)
b.text = tostring(c.b*255)
HEX.text = c:getHex()
hueBarMARKER.position = guiCoord(0,0,h/360,0)
end,
setCallback = function(c) callback = c end
}
end
return colourPicker

View File

@ -1,91 +0,0 @@
local controller = {}
function controller.roundToMultiple(number, multiple)
if multiple == 0 then
return number
end
return ((number % multiple) > multiple/2) and number + multiple - number%multiple or number - number%multiple
end
function controller.calculateVertices(block)
local vertices = {}
for x = -1,1,2 do
for y = -1,1,2 do
for z = -1,1,2 do
table.insert(vertices, block.position + block.rotation* (vector3(x,y,z) *block.size/2))
end
end
end
return vertices
end
-- these numbers are vertices indexes calculated in above function
local faces = {
{5, 6, 8, 7}, -- x forward,
{1, 2, 4, 3}, -- x backward,
{7, 8, 4, 3}, -- y upward,
{5, 6, 2, 1}, -- y downward,
{6, 2, 4, 8}, -- z forward
{5, 1, 3, 7} -- z backward
}
function controller.getCentreOfFace(block, face)
local vertices = controller.calculateVertices(block)
local avg = vector3(0,0,0)
for _,i in pairs(faces[face]) do
avg = avg + vertices[i]
end
return avg/4
end
function controller.vector3ToGuiCoord(vec)
local inFrontOfCamera, screenPos = workspace.camera:worldToScreen(vec)
if inFrontOfCamera then
return guiCoord(0, screenPos.x, 0, screenPos.y)
else
return guiCoord(-1,0,0,0)
end
end
function controller.roundVectorToMultiple(vec, multiple)
return vector3(controller.roundToMultiple(vec.x, multiple),
controller.roundToMultiple(vec.y, multiple),
controller.roundToMultiple(vec.z, multiple))
end
function controller.roundVectorWithToolSettings(vec)
local toolSettings = require("tevgit:create/controllers/toolSettings.lua")
local multiple = toolSettings.gridStep
vec.x = toolSettings.axis[1][2] and controller.roundToMultiple(vec.x, multiple) or vec.x
vec.y = toolSettings.axis[2][2] and controller.roundToMultiple(vec.y, multiple) or vec.y
vec.z = toolSettings.axis[3][2] and controller.roundToMultiple(vec.z, multiple) or vec.z
return vec
end
--Calculate median of vector
--modified from http://lua-users.org/wiki/SimpleStats
function controller.median(t, component)
local temp={}
for k,v in pairs(t) do
if v and v.position then
table.insert(temp, v.position[component])
end
end
table.sort( temp )
if math.fmod(#temp,2) == 0 then
return ( temp[#temp/2] + temp[(#temp/2)+1] ) / 2
else
return temp[math.ceil(#temp/2)]
end
end
function controller.startsWith(str, pat)
return str:len(1, pat:len()) == pat
end
return controller

View File

@ -1,63 +0,0 @@
-- Copyright (c) 2019 teverse.com
-- main.lua
return function(workshop)
local controllers = {
-- 1.0.0 has an internal console
-- = require("tevgit:create/controllers/console.lua"),
selection = require("tevgit:create/controllers/select.lua"),
theme = require("tevgit:create/controllers/theme.lua"),
ui = require("tevgit:create/controllers/ui.lua"),
camera = require("tevgit:create/controllers/camera.lua"),
tool = require("tevgit:create/controllers/tool.lua"),
property = require("tevgit:create/controllers/propertyEditor.lua"),
hotkeys = require("tevgit:create/controllers/hotkeys.lua"),
themeSwitcher = require("tevgit:create/controllers/themeSwitcher.lua"),
history = require("tevgit:create/controllers/history.lua"),
hierarchy = require("tevgit:create/controllers/hierarchy.lua")
}
controllers.ui.createMainInterface(workshop)
controllers.themeSwitcher.createUI(workshop)
--controllers.console.createConsole(workshop)
controllers.property.createUI(workshop)
controllers.history.giveWorkshop(workshop)
controllers.hierarchy.createUI(workshop)
--loaded here due to dependencies
controllers.env = require("tevgit:create/controllers/environment.lua")
controllers.toolSettings = require("tevgit:create/controllers/toolSettings.lua")
controllers.toolSettings.createUI(workshop)
local tools = {
add = require("tevgit:create/tools/add.lua"),
select = require("tevgit:create/tools/select.lua"),
move = require("tevgit:create/tools/move.lua"),
resize = require("tevgit:create/tools/resize.lua"),
rotate = require("tevgit:create/tools/rotate.lua"),
-- commented as there's a stack overflow issue:
--paint = require("tevgit:create/tools/paint.lua"),
}
-- create default environment
if workshop.gameFilePath == "" then
controllers.env.setDefault()
controllers.env.createStarterMap() -- Starter map, or the environment, may be overriden by teverse if the user is opening an existing .tev file.
end
wait(.3)
collectgarbage()
require("tevgit:create/controllers/dock.lua").loadSettings()
require("tevgit:create/controllers/devtools.lua")
require("tevgit:create/controllers/createTabController.lua")
collectgarbage()
controllers.ui.setLoading(false)
require("tevgit:create/controllers/scriptController.lua")
require("tevgit:create/controllers/testing.lua")
--wait(1)
--scriptEditor = require("tevgit:create/scriptEditor/main.lua")
engine.sounds:play("tevurl:sound/sample.ogg")
end

View File

@ -1,438 +0,0 @@
-- This script has been modified from https://github.com/LoganDark/lua-lexer
-- The original license has been included:
-------------------------------------------------------------------------------
-- MIT License
--
-- Copyright (c) 2018 LoganDark
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in all
-- copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- SOFTWARE.
local lexer = {}
function lookupify(src, list)
list = list or {}
if type(src) == 'string' then
for i = 1, src:len() do
list[src:sub(i, i)] = true
end
elseif type(src) == 'table' then
for i = 1, #src do
list[src[i]] = true
end
end
return list
end
local base_ident = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_'
local base_digits = '0123456789'
local base_operators = '+-*/^%#'
local chars = {
whitespace = lookupify(' \n\t\r'),
validEscapes = lookupify('abfnrtv"\'\\'),
ident = lookupify(
base_ident .. base_digits,
{
start = lookupify(base_ident),
}
),
digits = lookupify(
base_digits,
{
hex = lookupify(base_digits .. 'abcdefABCDEF')
}
),
symbols = lookupify(
base_operators .. ',{}[]();.:', {
equality = lookupify('~=><'),
operators = lookupify(base_operators)
}
)
}
local keywords = {
structure = lookupify({
'and', 'break', 'do', 'else', 'elseif', 'end', 'for', 'function',
'goto', 'if', 'in', 'local', 'not', 'or', 'repeat', 'return', 'then',
'until', 'while'
}),
values = lookupify({
'true', 'false', 'nil'
})
}
lexer.lex = function(text)
local pos = 1
local start = 1
local buffer = {}
local lines = {}
local function look(delta)
delta = pos + (delta or 0)
return text:sub(delta, delta)
end
local function get()
pos = pos + 1
return look(-1)
end
local function getDataLevel()
local num = 0
while look(num) == '=' do
num = num + 1
end
if look(num) == '[' then
pos = pos + num + 1
return num
end
end
local function getCurrentTokenText()
return text:sub(start, pos - 1)
end
local currentLineLength = 0
local lineoffset = 0
local function pushToken(type, text)
text = text or getCurrentTokenText()
local tk = buffer[#buffer]
if not tk or tk.type ~= type then
tk = {
type = type,
data = text,
posFirst = start - lineoffset,
posLast = pos - 1 - lineoffset
}
if tk.data ~= '' then
buffer[#buffer + 1] = tk
end
else
tk.data = tk.data .. text
tk.posLast = tk.posLast + text:len()
end
currentLineLength = currentLineLength + text:len()
start = pos
return tk
end
local function newline()
lines[#lines + 1] = buffer
buffer = {}
get()
pushToken('newline')
buffer[1] = nil
lineoffset = lineoffset + currentLineLength
currentLineLength = 0
end
local function getData(level, type)
while true do
local char = get()
if char == '' then
return
elseif char == '\n' then
pos = pos - 1
pushToken(type)
newline()
elseif char == ']' then
local valid = true
for i = 1, level do
if look() == '=' then
pos = pos + 1
else
valid = false
break
end
end
if valid and look() == ']' then
pos = pos - level - 1
return
end
end
end
end
local function chompWhitespace()
while true do
local char = look()
if char == '\n' then
pushToken('whitespace')
newline()
elseif chars.whitespace[char] then
pos = pos + 1
else
break
end
end
pushToken('whitespace')
end
while true do
chompWhitespace()
local char = get()
if char == '' then
break
elseif char == '-' and look() == '-' then
pos = pos + 1
if look() == '[' then
pos = pos + 1
local level = getDataLevel()
if level then
getData(level, 'comment')
pos = pos + level + 2
pushToken('comment')
else
while true do
local char2 = get()
if char2 == '' or char2 == '\n' then
pos = pos - 1
pushToken('comment')
if char2 == '\n' then
newline()
end
break
end
end
end
else
while true do
local char2 = get()
if char2 == '' or char2 == '\n' then
pos = pos - 1
pushToken('comment')
if char2 == '\n' then
newline()
end
break
end
end
end
pushToken('comment')
elseif char == '\'' or char == '"' then
pushToken('string_start')
while true do
local char2 = get()
if char2 == '\\' then
pos = pos - 1
pushToken('string')
get()
local char3 = get()
if chars.digits[char3] then
for i = 1, 2 do
if chars.digits[look()] then
pos = pos + 1
end
end
elseif char3 == 'x' then
if chars.digits.hex[look()] and chars.digits.hex[look(1)] then
pos = pos + 2
else
pushToken('unidentified')
end
elseif char3 == '\n' then
pos = pos - 1
pushToken('escape')
newline()
elseif not chars.validEscapes[char3] then
pushToken('unidentified')
end
pushToken('escape')
elseif char2 == '\n' then
pos = pos - 1
pushToken('string')
newline()
break
elseif char2 == char or char2 == '' then
pos = pos - 1
pushToken('string')
get()
break
end
end
pushToken('string_end')
elseif chars.ident.start[char] then
while chars.ident[look()] do
pos = pos + 1
end
local word = getCurrentTokenText()
if keywords.structure[word] then
pushToken('keyword')
elseif keywords.values[word] then
pushToken('value')
else
pushToken('ident')
end
elseif chars.digits[char] or (char == '.' and chars.digits[look()]) then
if char == '0' and look() == 'x' then
pos = pos + 1
while chars.digits.hex[look()] do
pos = pos + 1
end
else
while chars.digits[look()] do
pos = pos + 1
end
if look() == '.' then
pos = pos + 1
while chars.digits[look()] do
pos = pos + 1
end
end
if look():lower() == 'e' then
pos = pos + 1
if look() == '-' then
pos = pos + 1
end
while chars.digits[look()] do
pos = pos + 1
end
end
end
pushToken('number')
elseif char == '[' then
local level = getDataLevel()
if level then
pushToken('string_start')
getData(level, 'string')
pushToken('string')
pos = pos + level + 2
pushToken('string_end')
else
pushToken('symbol')
end
elseif char == '.' then
if look() == '.' then
pos = pos + 1
if look() == '.' then
pos = pos + 1
end
end
if getCurrentTokenText():len() == 3 then
pushToken('vararg')
else
pushToken('symbol')
end
elseif char == ':' and look() == ':' then
get()
pushToken('label_start')
chompWhitespace()
if chars.ident.start[look()] then
get()
while chars.ident[look()] do
get()
end
pushToken('label')
chompWhitespace()
if look() == ':' and look(1) == ':' then
get()
get()
pushToken('label_end')
end
end
elseif chars.symbols.equality[char] then
if look() == '=' then
pos = pos + 1
end
pushToken('operator')
elseif chars.symbols[char] then
if chars.symbols.operators[char] then
pushToken('operator')
else
pushToken('symbol')
end
else
pushToken('unidentified')
end
end
lines[#lines + 1] = buffer
return lines
end
return lexer;

View File

@ -1,130 +0,0 @@
-- very messy
-- i dont know why i did some of this like this
local lexer = require("tevgit:create/scriptEditor/lexer.lua")
local scriptEditor = {}
scriptEditor.mainFrame = engine.construct("guiFrame", engine.interface, {
size=guiCoord(1, 0, 1, 0),
backgroundColour=colour:fromRGB(40, 42, 54),
handleEvents=false,
zIndex=1002
})
scriptEditor.colouredText = engine.construct("guiTextBox", scriptEditor.mainFrame, {
size=guiCoord(1,-35,1,-10),
position=guiCoord(0,30,0,5),
zIndex=1003,
align=enums.align.topLeft,
fontFile = "FiraMono-Regular.ttf",
fontSize=18,
multiline=true,
readOnly=true,
wrapped = true,
textAlpha=0.8,
handleEvents = false,
text = "",
backgroundAlpha = 0
})
scriptEditor.mainText = engine.construct("guiTextBox", scriptEditor.mainFrame, {
size=guiCoord(1,-35,1,-10),
position=guiCoord(0,30,0,5),
zIndex=1002,
align=enums.align.topLeft,
fontFile = "FiraMono-Regular.ttf",
fontSize=18,
multiline=true,
readOnly=false,
wrapped = true,
textAlpha=0.2,
text = [[print("Hello Teverse!")]],
backgroundAlpha = 0
})
scriptEditor.colours = {
background = colour:fromRGB(40, 42, 54),
currentLine = colour:fromRGB(68, 71, 90),
selection = colour:fromRGB(68, 71, 90),
foreground = colour:fromRGB(248, 248, 242),
comment=colour:fromRGB(88,88,88),
string_start=colour:fromRGB(241,250,140), --YELLOW
string_end=colour:fromRGB(241,250,140),--yellow
string=colour:fromRGB(241,250,140),--yellow
escape=colour:fromRGB(189,147,249),--purple
keyword=colour:fromRGB(255,121,198),--cyan
value=colour:fromRGB(189,147,249),
ident=colour:fromRGB(80,250,123),
number=colour:fromRGB(189,147,249),
symbol=colour:fromRGB(255,121,198), --PINK
vararg=colour:fromRGB(255,184,108),
operator=colour:fromRGB(255,121,198),
label_start=colour:fromRGB(255, 184, 108),
label_end=colour:fromRGB(255, 184, 108),
label=colour:fromRGB(255, 184, 108),
unidentified=colour(1,0,0)
}
scriptEditor.lex = function()
--scriptEditor.colouredText:setTextColour(scriptEditor.colours["default"])
--local curC = 0
local text = scriptEditor.colouredText.text
scriptEditor.colouredText.textColour = colour(0.5, 0.5, 0.5)
--scriptEditor.colouredText.text = text
--wait()
--print(engine.lexer.lex, type(engine.lexer.lex))
local lexxed = lexer.lex(text)
local lineStart =0
local lineText = ""
--print(lexxed, type(lexxed))
for i, line in pairs(lexxed) do
local thisLine = 0
for t,v in pairs(line) do
v.posFirst = v.posFirst -1
scriptEditor.colouredText:setTextColour(lineStart + v.posFirst, lineStart + v.posLast, scriptEditor.colours[v.type] and scriptEditor.colours[v.type] or colour(0.5,0.5,0.5))
-- curC = curC + len
thisLine = v.posLast
end
lineStart = lineStart + thisLine + 1
lineText = lineText .. (i-1) .."\n"
end
lineText = lineText .. "-"
scriptEditor.leftText.text = lineText
end
scriptEditor.mainText:changed(function (txt)
scriptEditor.colouredText.text = scriptEditor.mainText.text .. "\n"
scriptEditor.lex()
end)
scriptEditor.leftFrame = engine.construct("guiFrame", scriptEditor.mainFrame, {
size=guiCoord(0, 30, 1, 0),
position=guiCoord(0, 0, 0, 0),
backgroundColour=scriptEditor.colours.background,
handleEvents=false,
zIndex=1002
})
scriptEditor.leftText = engine.construct("guiTextBox", scriptEditor.leftFrame, {
size=guiCoord(1,-10,1,-10),
position=guiCoord(0,5,0,5),
zIndex=1002,
align=enums.align.topLeft,
fontFile = "FiraMono-Regular.ttf",
fontSize=18,
multiline=true,
textColour=scriptEditor.colours.comment,
text = [[0]],
backgroundAlpha = 0
})
scriptEditor.lex()
return scriptEditor

View File

@ -1,318 +0,0 @@
--[[
Copyright 2019 Teverse
@File add.lua
@Author(s) Jay, Ly, joritochip
@Updated 5/8/19
--]]
-- TODO: Create a UI that allows the user to select what primitive to insert
-- UI should also allow user to specify default values for the created primitives
TOOL_NAME = "Add"
TOOL_ICON = "fa:s-plus-square"
TOOL_DESCRIPTION = "Use this to insert shapes."
local toolsController = require("tevgit:create/controllers/tool.lua")
local selectionController = require("tevgit:create/controllers/select.lua")
local uiController = require("tevgit:create/controllers/ui.lua")
local propertyController = require("tevgit:create/controllers/propertyEditor.lua")
local toolSettings = require("tevgit:create/controllers/toolSettings.lua")
local helpers = require("tevgit:create/helpers.lua")
local history = require("tevgit:create/controllers/history.lua")
local meshShortcuts = {
cube = "primitive:cube",
sphere = "primitive:sphere",
cylinder = "primitive:cylinder",
torus = "primitive:torus",
cone = "primitive:cone",
wedge = "primitive:wedge",
corner = "primitive:corner",
worker = "tevurl:3d/worker.glb",
duck = "tevurl:3d/Duck.glb",
avocado = "tevurl:3d/Avocado.glb",
}
local toolIsActive
-- storing tool specific content in tool.data isn't really needed anymore due to modules...
local placeholderBlock = engine.construct(
"block",
nil,
{
name = "createModeAddToolPlaceholderObject",
size = vector3(1, 1, 1),
static = true,
opacity = 0.5,
physics = false,
workshopLocked=true,
static=true,
castsShadows = false,
position = vector3(0, -100, 0)
}
)
local insertProps = {
opacity = 1,
castsShadows = true,
name = "newBlock",
static=true
}
local configWindow = uiController.createWindow(uiController.workshop.interface, guiCoord(0, 66, 0, 203), guiCoord(0, 140, 0, 48), "Inserter")
local editBtn = uiController.create("guiTextBox", configWindow.content, {
size = guiCoord(1,-10,1,-10),
position = guiCoord(0,5,0,5),
align = enums.align.middle,
text = "Edit Insertable"
}, "main")
local meshWindow = uiController.createWindow(uiController.workshop.interface, guiCoord(0, 66, 0, 266), guiCoord(0, 175, 0, 22), "Presets")
local curY = 0
local curX = 0
local btnNum = 0
for meshName, actualMeshName in pairs(meshShortcuts) do
local btn = uiController.create("guiTextBox", meshWindow.content, {
size = guiCoord(.5, -10, 0, 18),
position = guiCoord(curX, 5, 0, curY + 8),
borderRadius = 3,
text = meshName,
fontSize = 16,
align = enums.align.middle
}, "primary")
btn:mouseLeftReleased(function()
placeholderBlock.mesh = actualMeshName
end)
btnNum = btnNum + 1
if curX == 0.5 then
curY = curY + 24
curX = 0
else
curX = 0.5
end
end
local meshWindowY = (22 + (math.ceil(btnNum / 2) * 26))
print(btnNum)
print((math.ceil(btnNum / 2) * 26))
print(meshWindowY)
meshWindow.size = guiCoord(0, 175, 0, meshWindowY)
local editing = false
local db = false
editBtn:mouseLeftReleased(function ()
if editing then editing = false return end
if db then return end
db = true
editing = true
editBtn.text = "Back"
-- hide these from the property editor...
propertyController.excludePropertyList = {
["position"]=true,
["workshopLocked"]=true,
["name"]=true
}
local wasPropertyEditing = propertyController.instanceEditing
propertyController.generateProperties(placeholderBlock)
propertyController.window.visible = true
local startSize = propertyController.window.size
local startPos = propertyController.window.position
engine.tween:begin(propertyController.window, 0.25, {position = guiCoord(2/3, 0, 0, 100), size = guiCoord(1/3, -10, 1, -110)}, "inOutQuad")
local camPos = workspace.camera.position
local camRot = workspace.camera.rotation
placeholderBlock.position = vector3(0,-1000,0)
for p,v in pairs(insertProps) do
placeholderBlock[p] = v
end
workspace.camera.position = vector3(-3,-1000,-20)
workspace.camera:lookAt(vector3(-3,-999,0))
repeat
wait()
until propertyController.instanceEditing ~= placeholderBlock or not editing or not toolIsActive
for p,v in pairs(insertProps) do
insertProps[p] = placeholderBlock[p]
end
placeholderBlock.opacity = 0.5
placeholderBlock.name = "createModeAddToolPlaceholderObject"
placeholderBlock.castsShadows = false
placeholderBlock.physics = false
placeholderBlock.static = true
placeholderBlock.workshopLocked = true
workspace.camera.position = camPos
workspace.camera.rotation = camRot
engine.tween:begin(propertyController.window, 0.25, {position = startPos, size = startSize}, "inOutQuad")
wait(0.3)
propertyController.excludePropertyList = {}
if wasPropertyEditing then
propertyController.generateProperties(wasPropertyEditing)
end
editing = false
db=false
editBtn.text = "Edit Insertable"
end)
configWindow.visible = false
meshWindow.visible = false
local function onToolActivated(toolId)
configWindow.visible = true
meshWindow.visible = true
--[[
@Description
Initializes the process (making placeholders & events) for placing blocks
@Params
Integer, toolId
The unique {toolId} given after registering the tool
]]
selectionController.selectable = false
toolIsActive = true
local tool = toolsController.tools[toolId]
local mouseDown = 0
--[[tool.data.placeholderBlock = engine.construct(
"block",
nil,
{
name = "createModeAddToolPlaceholderObject",
size = vector3(1, 1, 1),
static = true,
opacity = 0.5,
physics = false,
castsShadows = false
}
)]]
local lastInsertPosition = vector3(0.1,12,04)
local function placeBlock()
if lastInsertPosition ~= placeholderBlock.position then
lastInsertPosition = placeholderBlock.position:clone()
local newBlock = placeholderBlock:clone()
newBlock.workshopLocked = false
newBlock.physics = true
newBlock.parent = engine.workspace
for p,v in pairs(insertProps) do
newBlock[p] = v
end
propertyController.generateProperties(newBlock)
selectionController.setSelection({newBlock})
-- Add this action to the history (Undo list)
history.addPoint(newBlock, "HISTORY_CREATED")
end
end
tool.data.mouseDownEvent = engine.input:mouseLeftPressed(function(input)
if input.systemHandled then return end
placeBlock()
local curTime = os.clock()
mouseDown = curTime
wait(1)
if (mouseDown == curTime) then
while (wait(.05)) and (mouseDown == curTime and toolsController.currentToolId == toolId) do
placeBlock()
end
end
end)
tool.data.mouseUpEvent = engine.input:mouseLeftReleased(function(input)
if input.systemHandled then return end
mouseDown = 0
end)
tool.data.keyPressedEvent = engine.input:keyPressed(function(input)
if input.systemHandled then return end
if input.key == enums.key.r then
placeholderBlock.rotation = placeholderBlock.rotation * quaternion:setEuler(0,math.rad(45),0)
end
end)
while (toolIsActive and wait() and placeholderBlock) do
if not editing then
local mouseHit = engine.physics:rayTestScreenAllHits(engine.input.mousePosition, placeholderBlock)
if #mouseHit > 0 then
placeholderBlock.position = helpers.roundVectorWithToolSettings(mouseHit[1].hitPosition + vector3(0, 0.5, 0))
end
end
end
placeholderBlock.position = vector3(0,-10000,0) --lol
end
local function onToolDeactivated(toolId)
configWindow.visible = false
meshWindow.visible = false
--[[
@Description
Clears up any loose ends during deactivation
@Params
Integer, toolId
The unique {toolId} given after registering the tool
]]
toolIsActive = false
selectionController.selectable = true
local tool = toolsController.tools[toolId]
tool.data.mouseDownEvent:disconnect()
tool.data.mouseDownEvent = nil
tool.data.mouseUpEvent:disconnect()
tool.data.mouseUpEvent = nil
tool.data.keyPressedEvent:disconnect()
tool.data.keyPressedEvent = nil
--tool.data.placeholderBlock:destroy()
--tool.data.placeholderBlock = nil
placeholderBlock.position = vector3(0,-10000,0) --lol
placeholderBlock.static = true
placeholderBlock.physics = false
end
return toolsController:register({
name = TOOL_NAME,
icon = TOOL_ICON,
description = TOOL_DESCRIPTION,
hotKey = enums.key.number1,
activated = onToolActivated,
deactivated = onToolDeactivated
})

View File

@ -1,230 +0,0 @@
--[[
This file remains here for reference.
This tool behaves as a move tool that operates on the local axes.
It was being modified for the scale too.
--]]
return error("bad.")
TOOL_NAME = "Resize"
TOOL_ICON = "fa:s-expand-arrows-alt"
TOOL_DESCRIPTION = "Use this to resize primitives."
local toolsController = require("tevgit:create/controllers/tool.lua")
local selectionController = require("tevgit:create/controllers/select.lua")
local toolSettings = require("tevgit:create/controllers/toolSettings.lua")
local helpers = require("tevgit:create/helpers.lua")
local function onToolActivated(toolId)
-- This is used to raycast the user's mouse position to an axis
local gridGuideline = engine.construct("block", workspace, {
size = vector3(0,0,0),
colour = colour(1,1,1),
opacity = 0,
workshopLocked = true,
castsShadows = false
})
toolsController.tools[toolId].data.gridGuideline = gridGuideline
-- TODO: Refactor code from old create mode...
-- Everything is essentially the same, apart from UI needs to use the ui controller
-- And also: engine.construct should be used throughout.
toolsController.tools[toolId].data.handles = {}
local components = {"x", "y", "z"}
local c = 1
local o = 0
local leftButtonDown = false
-- Probably can be improved
-- Creates two 'handles' for each axis.
-- Should work on all selected items.
for i = 1,6 do
local component = components[c]
local face = vector3(0,0,0)
face[component] = o == 0 and o-1 or o
local thisC = c
local handle = engine.construct("block", nil, {
name = "_CreateMode_",
castsShadows = false,
doNotSerialise=true,
opacity = 0,
renderQueue=1,
size = vector3(0.1, 0.1, 0.1),
colour = colour(c==1 and 1 or 0, c==2 and 1 or 0, c==3 and 1 or 0),
emissiveColour = colour(c==1 and .8 or 0, c==2 and .8 or 0, c==3 and .8 or 0),
workshopLocked = true
})
handle:mouseLeftPressed(function()
if leftButtonDown then return end -- how
leftButtonDown = handle
selectionController.selectable = false
gridGuideline.size = vector3(300, 0.1, 300)
gridGuideline.rotation = handle.rotation
gridGuideline.opacity = 0.5
gridGuideline.position = handle.position
local mouseHit = engine.physics:rayTestScreen( engine.input.mousePosition )
if not mouseHit or not mouseHit.object == gridGuideline then
return print("Error, couldn't cast ray to guideline.")
end
local mouseoffsets = {}
for _,v in pairs(selectionController.selection) do
mouseoffsets[v] = (mouseHit.hitPosition - v.position)
end
local lastHit = mouseHit.hitPosition
local gridStep = toolSettings.gridStep
repeat
if toolsController.currentToolId == toolId then
--Face camera on one Axis
--gridGuideline.position = handle.position
--gridGuideline.rotation = handle.rotation
if component == "y" then
local pos1 = gridGuideline.position
pos1[component] = 0
local pos2 = workspace.camera.position
pos2[component] = 0
local lookAt = gridGuideline.rotation:setLookRotation( pos1 - pos2 )
gridGuideline.rotation = lookAt * quaternion():setEuler(math.rad(45),0,0)
end
local mouseHits = engine.physics:rayTestScreenAllHits( engine.input.mousePosition )
local mouseHit = nil
-- We only want the gridGuideline
for _,hit in pairs(mouseHits) do
if hit.object == gridGuideline then
mouseHit = hit
goto skip_loop
end
end
::skip_loop::
if mouseHit and mouseHit.object == gridGuideline and lastHit ~= mouseHit.hitPosition then
local target = mouseHit.hitPosition
local moved = lastHit - target
lastHit = target
for _,v in pairs(selectionController.selection) do
if mouseoffsets[v] then
local newPos = target - mouseoffsets[v]
local pos = v.position
if component == "y" then
if gridStep > 0 and toolSettings.axis[2][2] then
pos.y = helpers.roundToMultiple(newPos.y, gridStep)
else
pos.y = newPos.y
end
else
if gridStep > 0 and toolSettings.axis[1][2] then
pos.x = helpers.roundToMultiple(newPos.x, gridStep)
else
pos.x = newPos.x
end
if gridStep > 0 and toolSettings.axis[3][2] then
pos.z = helpers.roundToMultiple(newPos.z, gridStep)
else
pos.z = newPos.z
end
end
v.position = pos
--engine.tween:begin(v, .05, {position = pos}, "inOutQuad")
end
end
end
end
wait()
until not leftButtonDown or not toolsController.currentToolId == toolId
delay(function() if not leftButtonDown then selectionController.selectable = true end end, 0.3)
if toolsController.currentToolId == toolId then
gridGuideline.size = vector3(0,0,0)
end
end)
table.insert(toolsController.tools[toolId].data.handles, {handle, face})
if i % 2 == 0 then
c=c+1
o = 0
else
o = o + 1
end
end
engine.input:mouseLeftReleased(function()
leftButtonDown = false
end)
updateHandles = function()
if #selectionController.selection == 0 then
for _,v in pairs(toolsController.tools[toolId].data.handles) do
v[1].size = vector3(0,0,0)
v[1].opacity = 0
end
else
for _,v in pairs(toolsController.tools[toolId].data.handles) do
local b = selectionController.selection[1]
v[1].position = b.position + b.rotation* ((v[2] * b.size/2) + (v[2]*1.5))
v[1]:lookAt(b.position)
v[1].rotation = v[1].rotation * quaternion():setEuler(math.rad(-90),math.rad(90),0)
v[1].size = vector3(0.35, 0.35, 0.35)
v[1].opacity = 1
end
end
end
toolsController.tools[toolId].data.keyDownEvent = engine.input:keyPressed(function ( inp )
if inp.key == enums.key.t then
--inputGrid.text = "0"
end
end)
toolsController.tools[toolId].data.boundingEvent = selectionController.boundingBox:changed(updateHandles)
updateHandles()
end
local function onToolDeactivated(toolId)
toolsController.tools[toolId].data.gridGuideline:destroy()
toolsController.tools[toolId].data.gridGuideline = nil
for _,v in pairs(toolsController.tools[toolId].data.handles) do
v[1]:destroy()
end
toolsController.tools[toolId].data.handles = nil
toolsController.tools[toolId].data.boundingEvent:disconnect()
toolsController.tools[toolId].data.boundingEvent = nil
end
return toolsController:register({
name = TOOL_NAME,
icon = TOOL_ICON,
description = TOOL_DESCRIPTION,
hotKey = enums.key.number4,
activated = onToolActivated,
deactivated = onToolDeactivated
})

View File

@ -1,244 +0,0 @@
--[[
Copyright 2019 Teverse
@File move.lua
@Author(s) Jay
--]]
TOOL_NAME = "Move"
TOOL_ICON = "fa:s-arrows-alt"
TOOL_DESCRIPTION = "Use this to move primitives along an axis."
local toolsController = require("tevgit:create/controllers/tool.lua")
local selectionController = require("tevgit:create/controllers/select.lua")
local toolSettings = require("tevgit:create/controllers/toolSettings.lua")
local helpers = require("tevgit:create/helpers.lua")
local history = require("tevgit:create/controllers/history.lua")
local mouseUpEvent
local function onToolActivated(toolId)
-- This is used to raycast the user's mouse position to an axis
local gridGuideline = engine.construct("block", workspace, {
size = vector3(0,0,0),
colour = colour(1,1,1),
opacity = 0,
workshopLocked = true,
castsShadows = false
})
toolsController.tools[toolId].data.gridGuideline = gridGuideline
-- TODO: Refactor code from old create mode...
-- Everything is essentially the same, apart from UI needs to use the ui controller
-- And also: engine.construct should be used throughout.
toolsController.tools[toolId].data.handles = {}
local components = {"x", "y", "z"}
local c = 1
local o = 0
local leftButtonDown = false
-- For history and adding undo points.
local originalPositions = {}
-- Probably can be improved
-- Creates two 'handles' for each axis.
-- Should work on all selected items.
for i = 1,6 do
local component = components[c]
local face = vector3(0,0,0)
face[component] = o == 0 and o-1 or o
local thisC = c
local handle = engine.construct("block", nil, {
name = "_CreateMode_",
castsShadows = false,
opacity = 0,
renderQueue=1,
doNotSerialise=true,
size = vector3(0.1, 0.1, 0.1),
colour = colour(c==1 and 1 or 0, c==2 and 1 or 0, c==3 and 1 or 0),
emissiveColour = colour(c==1 and .8 or 0, c==2 and .8 or 0, c==3 and .8 or 0),
workshopLocked = true,
mesh = "primitive:cone"
})
handle:mouseLeftPressed(function()
print("clicked")
if leftButtonDown then return end -- how
print("continued")
leftButtonDown = handle
selectionController.selectable = false
gridGuideline.size = vector3(300, 0.1, 300)
gridGuideline.rotation = handle.rotation
gridGuideline.position = handle.position
if component == "x" then
gridGuideline.rotation = gridGuideline.rotation * quaternion():setEuler(math.rad(-45),math.rad(-45),0)
end
local mouseHit = engine.physics:rayTestScreen( engine.input.mousePosition )
if not mouseHit or not mouseHit.object == gridGuideline then
return print("Error, couldn't cast ray to guideline.")
end
local mouseoffsets = {}
originalPositions = {}
for _,v in pairs(selectionController.selection) do
mouseoffsets[v] = (mouseHit.hitPosition - v.position)
originalPositions[v] = v.position
end
local lastHit = mouseHit.hitPosition
local gridStep = toolSettings.gridStep
-- IM CURRENTLY THINKING
-- Add special hook function to history.lua for only accepting values with intervals (needed for move & resize, maybe rotate)
-- and it gets the difference between two values
-- OR: Detect when mouse released from marker and then store that value. Add it to history if pos if updated again?
-- This could use lastHit or something similar?
repeat
if toolsController.currentToolId == toolId then
--Face camera on one Axis
gridGuideline.position = handle.position
if component == "x" then
local xVector1 = vector3(0, gridGuideline.position.y,gridGuideline.position.z)
local xVector2 = vector3(0, workspace.camera.position.y, workspace.camera.position.z)
local lookAt = gridGuideline.rotation:setLookRotation( xVector1 - xVector2 )
gridGuideline.rotation = lookAt * quaternion():setEuler(math.rad(45),0,0)
else
local pos1 = gridGuideline.position
pos1[component] = 0
local pos2 = workspace.camera.position
pos2[component] = 0
local lookAt = gridGuideline.rotation:setLookRotation( pos1 - pos2 )
gridGuideline.rotation = lookAt * quaternion():setEuler(math.rad(45),0,0)
end
local mouseHits = engine.physics:rayTestScreenAllHits( engine.input.mousePosition )
local mouseHit = nil
-- We only want the gridGuideline
for _,hit in pairs(mouseHits) do
if hit.object == gridGuideline then
mouseHit = hit
goto skip_loop
end
end
::skip_loop::
if mouseHit and mouseHit.object == gridGuideline and lastHit ~= mouseHit.hitPosition then
local target = mouseHit.hitPosition
lastHit = target
for _,v in pairs(selectionController.selection) do
if mouseoffsets[v] then
local newPos = target - mouseoffsets[v]
local pos = v.position
if gridStep > 0 and toolSettings.axis[thisC][2] then
pos[component] = helpers.roundToMultiple(newPos[component], gridStep)
else
pos[component] = newPos[component]
end
v.position = pos
--engine.tween:begin(v, .05, {position = pos}, "inOutQuad")
end
end
end
end
wait()
until not leftButtonDown or not toolsController.currentToolId == toolId
delay(function() if not leftButtonDown then selectionController.selectable = true end end, 0.3)
if toolsController.currentToolId == toolId then
gridGuideline.size = vector3(0,0,0)
end
end)
table.insert(toolsController.tools[toolId].data.handles, {handle, face})
if i % 2 == 0 then
c=c+1
o = 0
else
o = o + 1
end
end
mouseUpEvent = engine.input:mouseLeftReleased(function()
leftButtonDown = false
if originalPositions then
for item, pos in pairs(originalPositions) do
history.addPoint(item, "position", pos)
end
end
end)
updateHandles = function()
if selectionController.boundingBox.size == vector3(0,0,0) then
for _,v in pairs(toolsController.tools[toolId].data.handles) do
v[1].size = vector3(0,0,0)
v[1].opacity = 0
end
else
for _,v in pairs(toolsController.tools[toolId].data.handles) do
v[1].position = selectionController.boundingBox.position + selectionController.boundingBox.rotation* ((v[2] * selectionController.boundingBox.size/2) + (v[2]*1.5))
v[1]:lookAt(selectionController.boundingBox.position)
v[1].rotation = v[1].rotation * quaternion():setEuler(math.rad(90),0,0)
v[1].size = vector3(0.2, 0.4, 0.2)
v[1].opacity = 1
end
end
end
toolsController.tools[toolId].data.keyDownEvent = engine.input:keyPressed(function ( inp )
if inp.key == enums.key.t then
--inputGrid.text = "0"
end
end)
toolsController.tools[toolId].data.boundingEvent = selectionController.boundingBox:changed(updateHandles)
updateHandles()
end
local function onToolDeactivated(toolId)
toolsController.tools[toolId].data.gridGuideline:destroy()
toolsController.tools[toolId].data.gridGuideline = nil
for _,v in pairs(toolsController.tools[toolId].data.handles) do
v[1]:destroy()
end
toolsController.tools[toolId].data.handles = nil
toolsController.tools[toolId].data.boundingEvent:disconnect()
toolsController.tools[toolId].data.boundingEvent = nil
if mouseUpEvent then
mouseUpEvent:disconnect()
mouseUpEvent = nil
end
end
return toolsController:register({
name = TOOL_NAME,
icon = TOOL_ICON,
description = TOOL_DESCRIPTION,
hotKey = enums.key.number3,
activated = onToolActivated,
deactivated = onToolDeactivated
})

View File

@ -1,141 +0,0 @@
--[[
Copyright 2019 Teverse
@File paint.lua
@Author(s) TheCakeChicken
--]]
TOOL_NAME = "Paint"
TOOL_ICON = "fa:s-paint-brush"
TOOL_DESCRIPTION = "Use this to paint your blocks."
local toolsController = require("tevgit:create/controllers/tool.lua")
local uiController = require("tevgit:create/controllers/ui.lua")
local selectionController = require("tevgit:create/controllers/select.lua")
local toolActive = false
local currentColour = colour:fromRGB(255,255,255)
local configWindow = uiController.createWindow(uiController.workshop.interface, guiCoord(0, 66, 0, 203), guiCoord(0, 140, 0, 90), "Colour Picker")
local colourDisplay = engine.construct("guiFrame", configWindow.content, {
name = "colourPreview",
position = guiCoord(1, -25, 0, 5),
size = guiCoord(0, 20, 1, -10),
backgroundColour = currentColour
})
local redLabel = uiController.create("guiTextBox", configWindow.content, {
size = guiCoord(0, 20, 0, 16),
position = guiCoord(0, 5, 0, 5),
multiline = false,
fontSize = 16,
text = "R",
align = enums.align.middle
}, "mainTopBar")
local greenLabel = uiController.create("guiTextBox", configWindow.content, {
size = guiCoord(0, 20, 0, 16),
position = guiCoord(0, 5, 0, 26),
multiline = false,
fontSize = 16,
text = "G",
align = enums.align.middle
}, "mainTopBar")
local blueLabel = uiController.create("guiTextBox", configWindow.content, {
size = guiCoord(0, 20, 0, 16),
position = guiCoord(0, 5, 0, 47),
multiline = false,
fontSize = 16,
text = "B",
align = enums.align.middle
}, "mainTopBar")
local redInput = uiController.create("guiTextBox", configWindow.content, {
size = guiCoord(1, -60, 0, 16),
position = guiCoord(0, 30, 0, 5),
readOnly = false,
multiline = false,
fontSize = 18,
text = "255",
align = enums.align.middle,
name = "redInput"
}, "main")
local greenInput = uiController.create("guiTextBox", configWindow.content, {
size = guiCoord(1, -60, 0, 16),
position = guiCoord(0, 30, 0, 26),
readOnly = false,
multiline = false,
fontSize = 18,
text = "255",
align = enums.align.middle,
name = "greenInput"
}, "main")
local blueInput = uiController.create("guiTextBox", configWindow.content, {
size = guiCoord(1, -60, 0, 16),
position = guiCoord(0, 30, 0, 47),
readOnly = false,
multiline = false,
fontSize = 18,
text = "255",
align = enums.align.middle,
name = "blueInput"
}, "main")
configWindow.visible = false
local function updateColour()
currentColour = colour:fromRGB(tonumber(redInput.text), tonumber(greenInput.text), tonumber(blueInput.text))
colourDisplay.backgroundColour = currentColour
end
redInput:textInput(updateColour)
greenInput:textInput(updateColour)
blueInput:textInput(updateColour)
local function paintAllSelected()
if not toolActive then return end
for _,object in next,selectionController.selection do
object.colour = currentColour
end
end
local function onToolActivated(toolId)
configWindow.visible = true
toolActive = true
if selectionController.selection[1] then
local obj = selectionController.selection[1]
local r = obj.colour.r * 255
local g = obj.colour.g * 255
local b = obj.colour.b * 255
redInput.text = tostring(r)
greenInput.text = tostring(g)
blueInput.text = tostring(b)
updateColour()
end
selectionController.boundingBox:changed(paintAllSelected)
paintAllSelected()
end
local function onToolDeactivated(toolId)
configWindow.visible = false
toolActive = false
end
return toolsController:register({
name = TOOL_NAME,
icon = TOOL_ICON,
description = TOOL_DESCRIPTION,
hotKey = enums.key.number6,
activated = onToolActivated,
deactivated = onToolDeactivated
})

View File

@ -1,279 +0,0 @@
TOOL_NAME = "Resize"
TOOL_ICON = "fa:s-expand-arrows-alt"
TOOL_DESCRIPTION = "Use this to resize primitives."
local toolsController = require("tevgit:create/controllers/tool.lua")
local selectionController = require("tevgit:create/controllers/select.lua")
local toolSettings = require("tevgit:create/controllers/toolSettings.lua")
local helpers = require("tevgit:create/helpers.lua")
local history = require("tevgit:create/controllers/history.lua")
local updateHandles
local mouseUpEvent
local function onToolActivated(toolId)
-- This is used to raycast the user's mouse position to an axis
local gridGuideline = engine.construct("block", workspace, {
size = vector3(0,0,0),
colour = colour(1,1,1),
opacity = 0,
workshopLocked = true,
castsShadows = false
})
local originalSizes = {}
toolsController.tools[toolId].data.gridGuideline = gridGuideline
-- TODO: Refactor code from old create mode...
-- Everything is essentially the same, apart from UI needs to use the ui controller
-- And also: engine.construct should be used throughout.
toolsController.tools[toolId].data.handles = {}
local components = {"x", "y", "z"}
local c = 1
local o = 0
local leftButtonDown = false
-- Probably can be improved
-- Creates two 'handles' for each axis.
-- Should work on all selected items.
for i = 1,6 do
local component = components[c]
local face = vector3(0,0,0)
face[component] = o == 0 and o-1 or o
local thisC = c
local thisI = i
local handle = engine.construct("block", nil, {
name = "_CreateMode_",
castsShadows = false,
opacity = 0,
doNotSerialise=true,
renderQueue=1,
size = vector3(0.1, 0.1, 0.1),
colour = colour(c==1 and 1 or 0, c==2 and 1 or 0, c==3 and 1 or 0),
emissiveColour = colour(c==1 and .8 or 0, c==2 and .8 or 0, c==3 and .8 or 0),
workshopLocked = true,
mesh = "primitive:sphere"
})
handle:mouseLeftPressed(function()
if leftButtonDown then return end -- how
print("handle")
updateHandles()
leftButtonDown = handle
selectionController.selectable = false
gridGuideline.size = vector3(300, 0.2, 300)
gridGuideline.rotation = handle.rotation
gridGuideline.opacity = 0
gridGuideline.position = handle.position
wait()
local mouseHit = engine.physics:rayTestScreen( engine.input.mousePosition )
if not mouseHit or not mouseHit.object == gridGuideline then
return print("Error, couldn't cast ray to guideline.")
end
local mouseoffsets = {}
local lastHit = mouseHit.hitPosition
originalSizes = {}
for _,v in pairs(selectionController.selection) do
mouseoffsets[v] = {(lastHit - v.position), v.position, v.size}
originalSizes[v] = v.size
end
-- For history and adding undo points.
local gridStep = toolSettings.gridStep
repeat
if toolsController.currentToolId == toolId then
--Face camera on one Axis
--gridGuideline.position = handle.position
--gridGuideline.rotation = handle.rotation
if component == "y" then
local pos1 = gridGuideline.position
pos1[component] = 0
local pos2 = workspace.camera.position
pos2[component] = 0
local lookAt = gridGuideline.rotation:setLookRotation( pos1 - pos2 )
gridGuideline.rotation = lookAt * quaternion():setEuler(math.rad(45),0,0)
end
local mouseHits = engine.physics:rayTestScreenAllHits( engine.input.mousePosition )
local mouseHit = nil
-- We only want the gridGuideline
for _,hit in pairs(mouseHits) do
if hit.object == gridGuideline then
mouseHit = hit
goto skip_loop
end
end
::skip_loop::
if mouseHit and mouseHit.object == gridGuideline and lastHit ~= mouseHit.hitPosition then
local target = mouseHit.hitPosition
--print(target-lastHit)
local moved = lastHit - target
--lastHit = target
for _,v in pairs(selectionController.selection) do
if mouseoffsets[v] then
local newPos = target - mouseoffsets[v][1]
--print("moved 1", newPos - mouseoffsets[v][2])
local pos = mouseoffsets[v][2]:clone()
if component == "y" then
if gridStep > 0 and toolSettings.axis[2][2] then
pos.y = helpers.roundToMultiple(newPos.y, gridStep)
else
pos.y = newPos.y
end
else
-- newPos = newPos - vector3(0.05, 0, 0.05)
if gridStep > 0 and toolSettings.axis[1][2] then
pos.x = helpers.roundToMultiple(newPos.x, gridStep)
else
pos.x = newPos.x
end
if gridStep > 0 and toolSettings.axis[3][2] then
pos.z = helpers.roundToMultiple(newPos.z, gridStep)
else
pos.z = newPos.z
end
end
local totalMoved = pos - mouseoffsets[v][2]
local totalMovedSize = totalMoved:clone() * 2
if component ~= "x" then
totalMovedSize.x = 0
end
if component ~= "y" then
totalMovedSize.y = 0
end
if component ~= "z" then
totalMovedSize.z = 0
end
--print("moved 2", totalMoved)
if thisI % 2 == 0 then
v.size = (mouseoffsets[v][3] + totalMovedSize):max(vector3(0.1, 0.1, 0.1))
v.position = mouseoffsets[v][2] --+ (totalMoved/2)
else
v.size = (mouseoffsets[v][3] - totalMovedSize):max(vector3(0.1, 0.1, 0.1))
v.position = mouseoffsets[v][2] --+ (totalMoved/2)
end
--engine.tween:begin(v, .05, {position = pos}, "inOutQuad")
end
end
end
end
wait()
until not leftButtonDown or not toolsController.currentToolId == toolId
delay(function() if not leftButtonDown then selectionController.selectable = true end end, 0.3)
if toolsController.currentToolId == toolId then
gridGuideline.size = vector3(0,0,0)
end
end)
table.insert(toolsController.tools[toolId].data.handles, {handle, face})
if i % 2 == 0 then
c=c+1
o = 0
else
o = o + 1
end
end
mouseUpEvent = engine.input:mouseLeftReleased(function()
--print("Event fired")
leftButtonDown = false
if originalSizes then
for item, size in pairs(originalSizes) do
history.addPoint(item, "size", size)
end
end
end)
updateHandles = function()
if #selectionController.selection == 0 then
for _,v in pairs(toolsController.tools[toolId].data.handles) do
v[1].size = vector3(0,0,0)
v[1].opacity = 0
end
else
for _,v in pairs(toolsController.tools[toolId].data.handles) do
local b = selectionController.selection[1]
v[1].position = b.position + b.rotation* ((v[2] * b.size/2) + (v[2]*1.5))
v[1]:lookAt(b.position)
v[1].rotation = v[1].rotation * quaternion():setEuler(math.rad(-90),math.rad(90),0)
v[1].size = vector3(0.35, 0.35, 0.35)
v[1].opacity = 1
end
end
end
toolsController.tools[toolId].data.keyDownEvent = engine.input:keyPressed(function ( inp )
if inp.key == enums.key.t then
--inputGrid.text = "0"
end
end)
toolsController.tools[toolId].data.boundingEvent = selectionController.boundingBox:changed(updateHandles)
updateHandles()
end
local function onToolDeactivated(toolId)
toolsController.tools[toolId].data.gridGuideline:destroy()
toolsController.tools[toolId].data.gridGuideline = nil
for _,v in pairs(toolsController.tools[toolId].data.handles) do
v[1]:destroy()
end
toolsController.tools[toolId].data.handles = nil
toolsController.tools[toolId].data.boundingEvent:disconnect()
toolsController.tools[toolId].data.boundingEvent = nil
if mouseUpEvent then
mouseUpEvent:disconnect()
mouseUpEvent = nil
end
end
return toolsController:register({
name = TOOL_NAME,
icon = TOOL_ICON,
description = TOOL_DESCRIPTION,
hotKey = enums.key.number4,
activated = onToolActivated,
deactivated = onToolDeactivated
})

View File

@ -1,234 +0,0 @@
--[[
Copyright 2019 Teverse
@File rotate.lua
@Author(s) Jay
--]]
TOOL_NAME = "Rotate"
TOOL_ICON = "fa:s-sync-alt"
TOOL_DESCRIPTION = "Use this to rotate objects"
local sensitivity = 50
local toolsController = require("tevgit:create/controllers/tool.lua")
local selectionController = require("tevgit:create/controllers/select.lua")
local toolSettings = require("tevgit:create/controllers/toolSettings.lua")
local helpers = require("tevgit:create/helpers.lua")
local history = require("tevgit:create/controllers/history.lua")
local arrows = {
{},
{},
{}
}
-- Each axis gets four arrows...
-- This table maps each arrow index to an vertice index
local arrowsVerticesMap = {
{6, 4, 2, 1}, --x
{2, 1, 7, 6}, --y
{5, 7, 3, 1} --z
}
local function positionArrows()
if selectionController.boundingBox.size == vector3(0,0,0) then
for _,v in pairs(arrows) do
for i,arrow in pairs(v) do
arrow.physics = false
arrow.opacity = 0
end
end
else
local vertices = helpers.calculateVertices(selectionController.boundingBox)
for a,v in pairs(arrows) do
for i,arrow in pairs(v) do
if i == 2 then i = 3 end
arrow.physics = true
arrow.opacity = 1
arrow.position = vertices[arrowsVerticesMap[a][i]]
if a == 1 then
arrow.rotation = quaternion:setEuler(math.rad((i)*90), 0, math.rad(-90))
elseif a == 2 then
arrow.rotation = quaternion:setEuler(0, math.rad((i-1)*-90), 0)
else
arrow.rotation = quaternion:setEuler(math.rad((i-1)*-90), math.rad(90), math.rad(90))
end
end
end
end
end
local boundingEvent
-- calculates angle ABC
-- returns in radians
local function calculateAngleBetween3Points(a, b, c)
local v1 = a - b
local v2 = c - b
return math.acos(v1:normal():dot(v2:normal()))
end
local function calculateCircleAngle(hitbox, pos)
local hitboxPosition = hitbox.position
local hitboxRotation = hitbox.rotation
local hitboxUp = hitboxPosition + (hitboxRotation * vector3(0,0,-10))
local hitboxRight = hitboxPosition + (hitboxRotation * vector3(10,0,0))
local angle = calculateAngleBetween3Points(hitboxUp, hitboxPosition, pos)
if hitboxRight:dot(pos) < 0 then
angle = (math.pi-angle)+math.pi
end
return angle
end
local function onToolActivated(toolId)
for axis = 1, 3 do
local newArrow = engine.construct("block", engine.workspace, {
name = "_CreateMode_",
castsShadows = false,
opacity = 0,
renderQueue=1,
doNotSerialise=true,
size = vector3(.4, 0.1, .4),
colour = colour(axis == 1 and 1 or 0, axis == 2 and 1 or 0, axis == 3 and 1 or 0),
emissiveColour = colour(axis == 1 and 0.5 or 0, axis == 2 and 0.5 or 0, axis == 3 and 0.5 or 0),
workshopLocked = true,
mesh = "tevurl:3d/arrowCurved.glb"
})
newArrow:mouseLeftPressed(function ()
local hitbox = engine.construct("block", workspace, {
name = "_CreateMode_",
castsShadows = false,
opacity = 0,
renderQueue = 1,
doNotSerialise=true,
size = vector3(60, 0.1, 60),
workshopLocked = true,
position = helpers.getCentreOfFace(selectionController.boundingBox, (axis*2)-1),
rotation = newArrow.rotation
})
hitbox.rotation = hitbox.rotation:setLookRotation( hitbox.position - workspace.camera.position ) * quaternion():setEuler(math.rad(90),0,0)
--hitbox:lookAt(workspace.camera.position)
local mouseHits = engine.physics:rayTestScreenAllHits( engine.input.mousePosition )
local mouseHit = nil
for _,hit in pairs(mouseHits) do
if hit.object == hitbox then
mouseHit = hit
goto skip_loop
end
end
::skip_loop::
if not mouseHit then
print("Did not collide")
hitbox:destroy()
return nil
end
local startRotations = {}
for _,v in pairs(selectionController.selection) do
startRotations[v] = v.rotation
print("Start, ", v)
end
local start = mouseHit.hitPosition
while engine.input:isMouseButtonDown(enums.mouseButton.left) and wait() do
hitbox.rotation = hitbox.rotation:setLookRotation( hitbox.position - workspace.camera.position ) * quaternion():setEuler(math.rad(90),0,0)
local mouseHits = engine.physics:rayTestScreenAllHits( engine.input.mousePosition )
local mouseHit = nil
for _,hit in pairs(mouseHits) do
if hit.object == hitbox then
mouseHit = hit
goto skip_loop
end
end
::skip_loop::
if mouseHit then
local current = mouseHit.hitPosition
local diff = (start-current)
local travelled = diff:length()
-- length of vectors is never less than 0. let's fix that
if (newArrow.rotation * vector3(0,0,1)):dot(diff) < 0 then
--user moved their mouse in an opposite direction to the arrow
travelled = -travelled
end
local n = helpers.roundToMultiple(math.rad(travelled*sensitivity), toolSettings.rotateStep)
for _,v in pairs(selectionController.selection) do
if startRotations[v] then
local euler = vector3(
axis == 1 and n or 0,
axis == 2 and n or 0,
axis == 3 and n or 0
)
v.rotation = v.rotation * quaternion:setEuler(v.rotation:inverse() * euler)
end
end
if n ~= 0 then
start = current
end
end
end
hitbox:destroy()
for _,v in pairs(selectionController.selection) do
print("END", v)
if startRotations[v] and startRotations[v] ~= v.rotation then
history.addPoint(v, "rotation", startRotations[v])
end
end
end)
table.insert(arrows[axis], newArrow)
end
boundingEvent = selectionController.boundingBox:changed(positionArrows)
positionArrows()
end
local function onToolDeactivated(toolId)
boundingEvent:disconnect()
boundingEvent = nil
for _,v in pairs(arrows) do
for _,arrow in pairs(v) do
print(arrow)
arrow:destroy()
end
end
arrows = {
{},
{},
{}
}
end
return toolsController:register({
name = TOOL_NAME,
icon = TOOL_ICON,
description = TOOL_DESCRIPTION,
hotKey = enums.key.number5,
activated = onToolActivated,
deactivated = onToolDeactivated
})

View File

@ -1,163 +0,0 @@
--[[
Copyright 2019 Teverse
@File select.lua
@Author(s) Jay, joritochip
--]]
-- TODO: Create a UI that allows the user to input a step size
print("load")
TOOL_NAME = "Select"
TOOL_ICON = "fa:s-hand-paper"
TOOL_DESCRIPTION = "Use this select and move primitives."
local toolsController = require("tevgit:create/controllers/tool.lua")
local selectionController = require("tevgit:create/controllers/select.lua")
local toolSettings = require("tevgit:create/controllers/toolSettings.lua")
local helpers = require("tevgit:create/helpers.lua")
local function onToolActivated(toolId)
local mouseDown = 0
local applyRot = 0
local gridStep = toolSettings.gridStep
selectionController.selectable = true
toolsController.tools[toolId].data.mouseDownEvent = engine.input:mouseLeftPressed(function ( inp )
if not inp.systemHandled and #selectionController.selection > 0 then
applyRot = 0
local selectionAtBegin = selectionController.selection
local hit, didExclude = engine.physics:rayTestScreenAllHits(engine.input.mousePosition,
selectionAtBegin)
local objectSelectedHit = nil
local objectSelectedHits = engine.physics:rayTestScreenAllHits(engine.input.mousePosition)
for _,v in pairs(objectSelectedHits) do
for _,vv in pairs(selectionAtBegin) do
if vv == v.object then
objectSelectedHit = v
goto continue
end
end
end
::continue::
-- Didexclude is false if the user didnt drag starting from one of the selected items.
if didExclude == false or not objectSelectedHit then return end
local currentTime = os.clock()
mouseDown = currentTime
wait(0.25)
if mouseDown == currentTime then
--user held mouse down for 0.25 seconds,
--initiate drag
selectionController.selectable = false
hit = hit and hit[1] or nil
local startPosition = hit and hit.hitPosition or vector3(0,0,0)
local startOffset = (objectSelectedHit.object.position -objectSelectedHit.hitPosition)
startOffset.y =0
local lastPosition = startPosition
local startRotation = objectSelectedHit.object.rotation
local offsets = {}
for i,v in pairs(selectionAtBegin) do
if v ~= objectSelectedHit.object then
local relative = startRotation:inverse() * v.rotation;
local positionOffset = (relative*objectSelectedHit.object.rotation):inverse() * (v.position - objectSelectedHit.object.position)
offsets[v] = {positionOffset, relative}
end
end
local lastRot = applyRot
while mouseDown == currentTime and toolsController.currentToolId == toolId do
local currentHit = engine.physics:rayTestScreenAllHits(engine.input.mousePosition, selectionAtBegin)
if #currentHit >= 1 then
currentHit = currentHit[1]
-- supposed to get the face of the object the mouse it over, and then position the block to be on that face.
local forward = (currentHit.object.rotation * currentHit.hitNormal):normal()-- * quaternion:setEuler(0,math.rad(applyRot),0)
local currentPosition = (currentHit.hitPosition) + startOffset + (forward * (objectSelectedHit.object.size/2)) --+ (selectedItems[1].size/2)
currentPosition = helpers.roundVectorWithToolSettings(currentPosition)
if lastPosition ~= currentPosition or lastRot ~= applyRot then
lastRot = applyRot
lastPosition = currentPosition
local targetRot = startRotation * quaternion:setEuler(0,math.rad(applyRot),0)
--engine.tween:begin(selectionAtBegin[1], .2, {position = currentPosition,
-- rotation = targetRot }, "outQuad")
objectSelectedHit.object.position = currentPosition
objectSelectedHit.object.rotation = targetRot
for i,v in pairs(selectionAtBegin) do
if v ~= objectSelectedHit.object then
v.position = (currentPosition) + (offsets[v][2]*targetRot) * offsets[v][1]
v.rotation = offsets[v][2]*targetRot
--engine.tween:begin(v, .2, {position = (currentPosition) + (offsets[v][2]*targetRot) * offsets[v][1],
-- rotation = offsets[v][2]*targetRot }, "outQuad")
end
end
end
end
--calculateBoundingBox()
wait()
end
selectionController.selectable = true
end
end
end)
toolsController.tools[toolId].data.mouseUpEvent = engine.input:mouseLeftReleased(function ( inp )
mouseDown = 0
end)
toolsController.tools[toolId].data.keyPressedEvent = engine.input:keyPressed(function(input)
if input.systemHandled then return end
if input.key == enums.key.r then
applyRot = applyRot + 45
--gridStep = gridStep == 1 and 0 or 1
end
end)
end
local function onToolDeactivated(toolId)
--clean up
toolsController.tools[toolId].data.mouseDownEvent:disconnect()
toolsController.tools[toolId].data.mouseDownEvent = nil
toolsController.tools[toolId].data.mouseUpEvent:disconnect()
toolsController.tools[toolId].data.mouseUpEvent = nil
toolsController.tools[toolId].data.keyPressedEvent:disconnect()
toolsController.tools[toolId].data.keyPressedEvent = nil
end
return toolsController:register({
name = TOOL_NAME,
icon = TOOL_ICON,
description = TOOL_DESCRIPTION,
hotKey = enums.key.number2,
activated = onToolActivated,
deactivated = onToolDeactivated,
data = {axis={{"x", true},{"y", false},{"z", true}}}
})

View File

@ -38,7 +38,7 @@ local function runTutorial(module)
position = guiCoord(0,10,0,0),
backgroundAlpha = 0,
align = enums.align.middleLeft,
fontFile = "OpenSans-SemiBold.ttf",
fontFile = "local:OpenSans-SemiBold.ttf",
fontSize = 24,
text = tutorial.name
})
@ -48,7 +48,7 @@ local function runTutorial(module)
position = guiCoord(0,(title.textDimensions.x + 20),0,0),
backgroundAlpha = 0,
align = enums.align.middleLeft,
fontFile = "OpenSans-Regular.ttf",
fontFile = "local:OpenSans-Regular.ttf",
fontSize = 18,
textAlpha = 0.5,
text = tutorial.description
@ -93,7 +93,7 @@ local function runTutorial(module)
backgroundAlpha = 0,
align = enums.align.topLeft,
wrap = true,
fontFile = "OpenSans-Regular.ttf",
fontFile = "local:OpenSans-Regular.ttf",
fontSize = 20,
text = page,
textColour = colour:black(),
@ -105,7 +105,7 @@ local function runTutorial(module)
size = guiCoord(0, 120, 0, 24),
position = guiCoord(0,5,0,txt.textDimensions.y + 15),
align = enums.align.middle,
fontFile = "OpenSans-Regular.ttf",
fontFile = "local:OpenSans-Regular.ttf",
fontSize = 20,
text = "Next",
backgroundColour= colour(0.4, 0.4, 0.4),
@ -129,7 +129,7 @@ local function runTutorial(module)
backgroundAlpha = 0,
align = enums.align.topLeft,
wrap = true,
fontFile = "OpenSans-Regular.ttf",
fontFile = "local:OpenSans-Regular.ttf",
fontSize = 20,
text = v,
textColour = colour:black(),
@ -143,7 +143,7 @@ local function runTutorial(module)
size = guiCoord(0, 120, 0, 22),
position = guiCoord(0,5,0,y),
align = enums.align.middle,
fontFile = "OpenSans-Regular.ttf",
fontFile = "local:OpenSans-Regular.ttf",
fontSize = 20,
text = "Continue",
backgroundColour= colour(0.4, 0.4, 0.4),
@ -165,7 +165,7 @@ local function runTutorial(module)
size = guiCoord(0, 120, 0, 22),
position = guiCoord(0,5,0,y),
align = enums.align.middle,
fontFile = "OpenSans-Regular.ttf",
fontFile = "local:OpenSans-Regular.ttf",
fontSize = 20,
text = v.btnText,
backgroundColour= colour(0.4, 0.4, 0.4),
@ -215,7 +215,7 @@ local function createMainInterface()
position = guiCoord(0,10,0,10),
backgroundAlpha = 0,
align = enums.align.middleLeft,
fontFile = "OpenSans-SemiBold.ttf",
fontFile = "local:OpenSans-SemiBold.ttf",
fontSize = 24,
text = section
})
@ -249,7 +249,7 @@ local function createMainInterface()
backgroundAlpha = 0.1,
textAlpha = 0.5,
align = enums.align.middle,
fontFile = "OpenSans-SemiBold.ttf",
fontFile = "local:OpenSans-SemiBold.ttf",
fontSize = 20,
backgroundColour= colour:black(),
text = tostring(i),
@ -261,7 +261,7 @@ local function createMainInterface()
position = guiCoord(0,40,0,5),
backgroundAlpha = 0,
align = enums.align.middleLeft,
fontFile = "OpenSans-Regular.ttf",
fontFile = "local:OpenSans-Regular.ttf",
fontSize = 20,
text = tutorial[1],
handleEvents = false,

File diff suppressed because it is too large Load Diff

View File

@ -64,18 +64,18 @@ local function updatePositions(frame)
frame.icon.texture = regularIconWithChildren
frame.icon.imageAlpha = 1
frame.textAlpha = 1
frame.fontFile = "OpenSans-SemiBold.ttf"
frame.fontFile = "local:OpenSans-SemiBold.ttf"
else
-- object has no children
frame.icon.texture = regularIconWithOutChildren
frame.icon.imageAlpha = .2
frame.textAlpha = .6
frame.fontFile = "OpenSans-Regular.ttf"
frame.fontFile = "local:OpenSans-Regular.ttf"
end
else
-- object is expanded
frame.textAlpha = 0.6
frame.fontFile = "OpenSans-Regular.ttf"
frame.fontFile = "local:OpenSans-Regular.ttf"
frame.icon.imageAlpha = 0.4
frame.icon.texture = expandedIcon
end
@ -137,8 +137,8 @@ local function createHierarchyButton(object, guiParent)
end
controller.scrollView.canvasSize =
guiCoord(1, 0, 0, updatePositions())
if object.className == "scriptSource" or object.className ==
"scriptContainer" then
if object.className == "script" then
object:editExternal()
-- require("tevgit:create/controllers/scriptController.lua").editScript(object)
end
else
@ -190,7 +190,9 @@ local function createHierarchyButton(object, guiParent)
if object:isA("luaSharedFolder") or object:isA("luaServerFolder") or
object:isA("luaClientFolder") then
context.bind(btn, context.exampleOptions)
context.bind(btn, {
{name = "Add Script", callback = function() engine.construct("script", object) end}
})
else
-- selectionController.applyContext(btn)
end

View File

@ -64,9 +64,9 @@ controller.generateMenu = function(options, position)
textAlpha = 0.6
}, "primaryText")
if options.callback then
if option.callback then
btn:mouseLeftReleased(function ()
options.callback()
option.callback()
menu:destroy()
controller.currentContextMenu = nil
end)

View File

@ -205,7 +205,7 @@ return {
zIndex = 2,
text = "Continue",
align = enums.align.middle,
fontFile = "OpenSans-Bold.ttf"
fontFile = "local:OpenSans-Bold.ttf"
}, themer.types.primaryVariant)
if not callback then