mirror of https://github.com/teverse/teverse
Compare commits
3 Commits
ce09c81403
...
2f894740e0
Author | SHA1 | Date |
---|---|---|
teverse | 2f894740e0 | |
teverse | 9646955c60 | |
Jay | 99a26c634e |
|
@ -0,0 +1 @@
|
|||
.DS_Store
|
|
@ -0,0 +1,76 @@
|
|||
local keybinder = require("tevgit:workshop/controllers/core/keybinder.lua")
|
||||
local history = require("tevgit:workshop/controllers/core/history.lua")
|
||||
local selection = require("tevgit:workshop/controllers/core/selection.lua")
|
||||
|
||||
local clipboard = {}
|
||||
|
||||
keybinder:bind({
|
||||
name = "copy",
|
||||
key = enums.key.c,
|
||||
priorKey = enums.key.leftCtrl,
|
||||
action = function()
|
||||
clipboard = selection.selection
|
||||
end
|
||||
})
|
||||
|
||||
keybinder:bind({
|
||||
name = "paste",
|
||||
key = enums.key.v,
|
||||
priorKey = enums.key.leftCtrl,
|
||||
action = function()
|
||||
history.beginAction(workspace, "Paste")
|
||||
|
||||
local bounds = aabb()
|
||||
if #clipboard > 0 then
|
||||
bounds.min = clipboard[1].position
|
||||
bounds.max = clipboard[1].position
|
||||
end
|
||||
|
||||
-- translates the pasted objects by:
|
||||
local offset = vector3(0, 0, 0)
|
||||
-- pass the clipboard to calculate bounds
|
||||
for _,v in pairs(clipboard) do
|
||||
if type(v.position) == "vector3" and type(v.size) == "vector3" then
|
||||
bounds:expand(v.position + (v.size / 2))
|
||||
bounds:expand(v.position - (v.size / 2))
|
||||
end
|
||||
end
|
||||
offset = vector3(0, bounds.max.y - bounds.min.y, 0)
|
||||
|
||||
local centre = bounds:getCentre()
|
||||
|
||||
local clones = {}
|
||||
for _,v in pairs(clipboard) do
|
||||
if v and v.alive then
|
||||
local new = v:clone()
|
||||
new.parent = workspace
|
||||
if type(new.position) == "vector3" then
|
||||
new.position = new.position + offset
|
||||
end
|
||||
table.insert(clones, new)
|
||||
end
|
||||
end
|
||||
|
||||
history.endAction()
|
||||
selection.setSelection(clones)
|
||||
end
|
||||
})
|
||||
|
||||
keybinder:bind({
|
||||
name = "duplicate",
|
||||
key = enums.key.d,
|
||||
priorKey = enums.key.leftCtrl,
|
||||
action = function()
|
||||
history.beginAction(workspace, "Duplicate")
|
||||
local clones = {}
|
||||
for _,v in pairs(selection.selection) do
|
||||
if v and v.alive then
|
||||
local new = v:clone()
|
||||
new.parent = workspace
|
||||
table.insert(clones, new)
|
||||
end
|
||||
end
|
||||
history.endAction()
|
||||
selection.setSelection(clones)
|
||||
end
|
||||
})
|
|
@ -53,12 +53,11 @@ local function destroyingListener()
|
|||
if not changes[changedObject] then
|
||||
changes[changedObject] = {}
|
||||
end
|
||||
|
||||
-- Object is being destroyed, let's save a copy of all their writable properties so the user can undo this action
|
||||
local members = workshop:getMembersOfObject( changedObject )
|
||||
local members = shared.workshop:getMembersOfObject( changedObject )
|
||||
local toStore = {}
|
||||
for _, prop in pairs(members) do
|
||||
local val = object[prop.property]
|
||||
local val = changedObject[prop.property]
|
||||
local pType = type(val)
|
||||
|
||||
if prop.writable and pType ~= "function" then
|
||||
|
@ -66,7 +65,9 @@ local function destroyingListener()
|
|||
toStore[prop.property] = val
|
||||
end
|
||||
end
|
||||
|
||||
toStore["parent"] = changedObject.parent
|
||||
toStore["className"] = changedObject.className
|
||||
|
||||
table.insert(destroyedObjects, toStore)
|
||||
end
|
||||
|
@ -98,13 +99,13 @@ local function beginAction( object, name )
|
|||
if type(object) == "table" then
|
||||
for _,v in pairs(object) do
|
||||
table.insert(eventListeners, v:onSync("changed", changedListener))
|
||||
table.insert(eventListeners, v:onSync("destroying", destroyingListener))
|
||||
table.insert(eventListeners, v:onSync("childAdded", ChildAddedListener))
|
||||
table.insert(eventListeners, v:onSync("destroying", destroyingListener))
|
||||
end
|
||||
else
|
||||
table.insert(eventListeners, object:onSync("changed", changedListener))
|
||||
table.insert(eventListeners, object:onSync("destroying", destroyingListener))
|
||||
table.insert(eventListeners, object:onSync("childAdded", ChildAddedListener))
|
||||
table.insert(eventListeners, object:onSync("destroying", destroyingListener))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -139,6 +140,15 @@ end
|
|||
|
||||
local function undo()
|
||||
if actions[pointer] ~= nil then
|
||||
|
||||
-- destroyed objects (restore)
|
||||
for _, properties in pairs(actions[pointer][4]) do
|
||||
local obj = engine[properties["className"]]()
|
||||
for property, value in pairs(properties) do
|
||||
obj[property] = value
|
||||
end
|
||||
end
|
||||
|
||||
for object, properties in pairs(actions[pointer][3]) do
|
||||
if object and object.alive then
|
||||
for property, values in pairs(properties) do
|
||||
|
@ -147,7 +157,8 @@ local function undo()
|
|||
object[property] = values[1]
|
||||
end
|
||||
else
|
||||
warn("need to put logic here")
|
||||
for k,v in pairs(properties) do print(k,v) end
|
||||
warn("There was a change recorded, but we couldn't find the object.")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -165,10 +176,14 @@ local function redo()
|
|||
if actions[pointer + 1] ~= nil then
|
||||
pointer = pointer + 1
|
||||
for object, properties in pairs(actions[pointer][3]) do
|
||||
for property, values in pairs(properties) do
|
||||
--values[1] = original value
|
||||
--values[2] = changed value
|
||||
object[property] = values[2]
|
||||
if object and object.alive then
|
||||
for property, values in pairs(properties) do
|
||||
--values[1] = original value
|
||||
--values[2] = changed value
|
||||
object[property] = values[2]
|
||||
end
|
||||
else
|
||||
warn("There was a change recorded, but we couldn't find the object.")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -34,7 +34,12 @@ function hotkeysController:handle(inputObject)
|
|||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
-- bad: seperate pass because we prioritise prior key commands.
|
||||
for key, data in pairs(self.bindings) do
|
||||
if (data.action) then
|
||||
if (inputObject.key == key) then
|
||||
data.action()
|
||||
return
|
||||
|
|
|
@ -11,7 +11,9 @@ local ui = require("tevgit:workshop/controllers/ui/core/ui.lua")
|
|||
local shared = require("tevgit:workshop/controllers/shared.lua")
|
||||
|
||||
local clickEvent = nil
|
||||
local keyEvent = nil
|
||||
local settingsGui = nil
|
||||
local isDragging = false
|
||||
|
||||
return {
|
||||
name = toolName,
|
||||
|
@ -52,6 +54,19 @@ return {
|
|||
gridStep = tonumber(gridStepInput.text) or 0
|
||||
end)
|
||||
|
||||
local offsets = {}
|
||||
keyEvent = engine.input:keyPressed(function( inputObj )
|
||||
if inputObj.key == enums.key.r and isDragging then
|
||||
local targetRot = quaternion:setEuler(0,math.rad(-45),0)
|
||||
for _,v in pairs(selection.selection) do
|
||||
if offsets[v] then
|
||||
offsets[v][2] = offsets[v][2] * targetRot
|
||||
v.rotation = offsets[v][2]
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Set the event listener to a variable so we can disconnect this handler
|
||||
-- when the tool is deactivated
|
||||
clickEvent = engine.input:mouseLeftPressed(function ( inputObj )
|
||||
|
@ -84,9 +99,12 @@ return {
|
|||
local mouseOffset = hit.hitPosition - centre
|
||||
|
||||
-- calculate every selected item's offset from the centre
|
||||
local offsets = {}
|
||||
offsets = {}
|
||||
for _,v in pairs(selection.selection) do
|
||||
offsets[v] = v.position - centre
|
||||
--offsets[v] = v.position - centre
|
||||
local relative = quaternion(0, 0, 0, 1) * v.rotation;
|
||||
local positionOffset = (relative*quaternion(0, 0, 0, 1)):inverse() * (v.position - centre)
|
||||
offsets[v] = {positionOffset, relative}
|
||||
end
|
||||
|
||||
-- tell history to monitor changes we make to selected items
|
||||
|
@ -99,6 +117,8 @@ return {
|
|||
rotation = quaternion:setEuler(math.rad(90), 0, 0)
|
||||
})
|
||||
|
||||
isDragging = true
|
||||
|
||||
while engine.input:isMouseButtonDown(enums.mouseButton.left) do
|
||||
-- fire a ray, exclude selected items.
|
||||
local hits, didExclude = engine.physics:rayTestScreenAllHits(engine.input.mousePosition, selection.selection)
|
||||
|
@ -111,7 +131,9 @@ return {
|
|||
local minY = hits[1].hitPosition.y
|
||||
for _,v in pairs(selection.selection) do
|
||||
if offsets[v] then
|
||||
v.position = newCentre + offsets[v]
|
||||
v.position = newCentre + (offsets[v][2] * offsets[v][1])
|
||||
|
||||
-- Calculate the lowest point in the selection:
|
||||
local size = v.size or vector3(0,0,0)
|
||||
minY = math.min(minY, v.position.y - (size.y/2))
|
||||
avgPos = avgPos + v.position
|
||||
|
@ -135,6 +157,8 @@ return {
|
|||
wait()
|
||||
end
|
||||
|
||||
isDragging = false
|
||||
|
||||
history.endAction()
|
||||
|
||||
grid:destroy()
|
||||
|
@ -161,6 +185,11 @@ return {
|
|||
settingsGui = nil
|
||||
end
|
||||
|
||||
if keyEvent then
|
||||
keyEvent:disconnect()
|
||||
keyEvent = nil
|
||||
end
|
||||
|
||||
if clickEvent then
|
||||
clickEvent:disconnect()
|
||||
clickEvent = nil
|
||||
|
|
|
@ -50,7 +50,7 @@ local function draw()
|
|||
ui.create("guiTextBox", window.content, {
|
||||
size = guiCoord(1, 0, 0, 18),
|
||||
position = guiCoord(0, 0, 0, yPos),
|
||||
text = string.format("[ %s ] %s (change: %i, add: %i, rem: %i)", formattedDate, actionName, history.count(action[3]), history.count(action[4]), history.count(action[5]))
|
||||
text = string.format("[ %s ] %s (change: %i, add: %i, rem: %i)", formattedDate, actionName, history.count(action[3]), #action[4], #action[5])
|
||||
}, "backgroundText")
|
||||
|
||||
yPos = yPos + 20
|
||||
|
|
|
@ -196,7 +196,7 @@ createInputs = {
|
|||
backgroundAlpha = 0.25,
|
||||
readOnly = false,
|
||||
multiline = false,
|
||||
wrapped = true,
|
||||
wrap = true,
|
||||
fontSize = 18,
|
||||
name = "input",
|
||||
size = guiCoord(1, -4, 0, 18),
|
||||
|
|
|
@ -69,7 +69,9 @@ local function beginLoad(workshop)
|
|||
-- Okay now we can load remote files whilst the user is looking at a loading screen.
|
||||
shared.controllers.env = require("tevgit:workshop/controllers/environment/main.lua")
|
||||
|
||||
shared.controllers.history = require("tevgit:workshop/controllers/core/history.lua")
|
||||
shared.controllers.history = require("tevgit:workshop/controllers/core/history.lua")
|
||||
|
||||
shared.controllers.clipboard = require("tevgit:workshop/controllers/core/clipboard.lua")
|
||||
|
||||
-- Create the Teverse interface
|
||||
require("tevgit:workshop/controllers/ui/createInterface.lua")
|
||||
|
|
Loading…
Reference in New Issue