Fixed canvas, working on simulating events

This commit is contained in:
Ryan Ward 2023-12-21 02:14:42 -05:00
parent 65d7009548
commit 6cbd09a460
4 changed files with 126 additions and 96 deletions

View File

@ -1,98 +1,21 @@
local gui = require("gui") local gui = require("gui")
local multi, thread = require("multi"):init()
local canvas = {} function newCanvas()
local c = gui:newVirtualFrame(0,0,0,0,0,0,1,1)
-- Run the canvas logic within another processor
local proc = gui:newProcessor("Canvas Handler")
local updater = proc:newLoop().OnLoop
local draw_handler = gui.draw_handler
function canvas:newCanvas()
local c = {}
setmetatable(c, gui)
local active = false
c.type = gui.TYPE_FRAME
c.children = {}
c.dualDim = gui:newDualDim()
c.x = 0
c.y = 0
local w, h = love.graphics.getDimensions()
c.dualDim.offset.size.x = w
c.dualDim.offset.size.y = h
c.w = w
c.h = h
c.parent = c
table.insert(canvas, c)
proc:newThread(function()
while true do
print("Holding...")
thread.hold(c.isActive)
local children = c:getAllChildren()
for i = 1, #children do
local child = children[i]
if child.effect then
child.effect(function() draw_handler(child, true) end)
else
draw_handler(child, true)
end
end
first_loop = true
end
end)
function c:isActive(b)
if b == nil then
return active
end
active = b
end
function c:OnUpdate(func)
if type(self) == "function" then func = self end
updater(function() func(c) end)
end
function c:newThread(func)
return proc:newThread("ThreadHandler<" .. self.type .. ">", func, self, thread)
end
function c:swap(c1, c2) function c:swap(c1, c2)
local ch1 = c1:getChildren() local temp = c1.children
local ch2 = c2:getChildren() c1.children = c2.children
for i = 1, #ch1 do c2.children = temp
ch1[i]:setParent(c2) for i,v in pairs(c1.children) do
v.parent = c1
end end
for i = 1, #ch2 do for i,v in pairs(c2.children) do
ch2[i]:setParent(c1) v.parent = c2
end end
end end
return c return c
end end
gui.Events.OnResized(proc:newFunction(function(w, h) return newCanvas
for i = 1, #canvas do
local c = canvas[i]
if gui.aspect_ratio then
local nw, nh, xt, yt = gui.GetSizeAdjustedToAspectRatio(w, h)
c.x = xt
c.y = yt
c.dualDim.offset.size.x = nw
c.dualDim.offset.size.y = nh
c.w = nw
c.h = nh
else
c.dualDim.offset.size.x = w
c.dualDim.offset.size.y = h
c.w = w
c.h = h
end
end
end))
return canvas

108
core/simulate.lua Normal file
View File

@ -0,0 +1,108 @@
local gui = require("gui")
local multi, thread = require("multi"):init()
local transition = require("gui.elements.transitions")
-- Triggers press then release
local function getPosition(obj, x, y)
if not x or y then
local cx, cy, w, h = obj:getAbsolutes()
return cx + w/2, cy + h/2
else
return x, y
end
end
proc = gui:getProcessor()
local simulate = {}
local cursor = false
local smooth = false
function simulate:moveCursor(bool)
cursor = bool
end
function simulate:smoothMovement(bool)
smooth = bool
end
function simulate:Press(button, x, y, istouch)
if self then
x, y = getPosition(self, x, y)
elseif x == nil or y == nil then
x, y = love.mouse.getPosition()
end
if cursor then
love.mouse.setPosition(x, y)
end
gui.Events.OnMousePressed:Fire(x, y, button or gui.MOUSE_PRIMARY, istouch or false)
end
function simulate:Release(button, x, y, istouch)
if self then
x, y = getPosition(self, x, y)
elseif x == nil or y == nil then
x, y = love.mouse.getPosition()
end
if cursor then
love.mouse.setPosition(x, y)
end
gui.Events.OnMouseReleased:Fire(x, y, button or gui.MOUSE_PRIMARY, istouch or false)
end
simulate.Click = proc:newFunction(function(self, button, x, y, istouch)
if self then
x, y = getPosition(self, x, y)
elseif x == nil or y == nil then
x, y = love.mouse.getPosition()
end
if cursor then
love.mouse.setPosition(x, y)
end
gui.Events.OnMousePressed:Fire(x, y, button or gui.MOUSE_PRIMARY, istouch or false)
thread.skip(1)
gui.Events.OnMouseReleased:Fire(x, y, button or gui.MOUSE_PRIMARY, istouch or false)
end, true)
simulate.Move = proc:newFunction(function(self, dx, dy, x, y, istouch)
local dx, dy = dx or 0, dy or 0
if self then
x, y = getPosition(self, x, y)
elseif x == nil or y == nil then
x, y = love.mouse.getPosition()
end
gui.Events.OnMouseMoved:Fire(x, y, 0, 0, istouch or false)
thread.skip(1)
if smooth then
local gx = transition.glide(0, dx, .25)
local gy = transition.glide(0, dy, .25)
local xx = gx()
xx.OnStep(function(p)
_x, _y = love.mouse.getPosition()
if cursor then
love.mouse.setPosition(x + p, _y)
else
gui.Events.OnMouseMoved:Fire(x + p, _y, 0, 0, istouch or false)
end
end)
local yy = gy()
yy.OnStep(function(p)
_x, _y = love.mouse.getPosition()
if cursor then
love.mouse.setPosition(_x, y + p)
else
gui.Events.OnMouseMoved:Fire(_x, y + p, 0, 0, istouch or false)
end
end)
thread.hold(xx.OnStop * yy.OnStop)
gui.Events.OnMouseMoved:Fire(x + dx, y + dy, 0, 0, istouch or false)
else
if cursor then
love.mouse.setPosition(x + dx, y + dy)
end
gui.Events.OnMouseMoved:Fire(x + dx, y + dy, 0, 0, istouch or false)
end
end, true)
return simulate

View File

@ -15,7 +15,7 @@ transition.__call = function(t, start, stop, time, ...)
local args = {...} local args = {...}
return function() return function()
if not start or not stop then return multi.error("start and stop must be supplied") end if not start or not stop then return multi.error("start and stop must be supplied") end
if start == stop then return multi.error("start and stop cannot be the same!") end if start == stop then multi.print("start and stop cannot be the same!") return {OnStep = function() end, OnStop = function() end} end
local handle = t.func(t, start, stop, time or 1, unpack(args)) local handle = t.func(t, start, stop, time or 1, unpack(args))
return { return {
OnStep = handle.OnStatus, OnStep = handle.OnStatus,

View File

@ -327,6 +327,11 @@ function gui:bottomStack()
table.insert(siblings, 1, self) table.insert(siblings, 1, self)
end end
function gui:OnUpdate(func) -- Not crazy about this approach, will probably rework this
if type(self) == "function" then func = self end
mainupdater(function() func(c) end)
end
local mainupdater = updater:newLoop().OnLoop local mainupdater = updater:newLoop().OnLoop
function gui:canPress(mx, my) -- Get the intersection of the clip area and the self then test with the clip, otherwise test as normal function gui:canPress(mx, my) -- Get the intersection of the clip area and the self then test with the clip, otherwise test as normal
@ -480,8 +485,8 @@ function gui:newBase(typ, x, y, w, h, sx, sy, sw, sh, virtual)
end end
return false return false
end end
setmetatable(c, self)
setmetatable(c, gui) c.__index = self.__index
c.__variables = {clip = {false, 0, 0, 0, 0}} c.__variables = {clip = {false, 0, 0, 0, 0}}
c.active = true c.active = true
c.type = typ c.type = typ
@ -586,11 +591,6 @@ function gui:newBase(typ, x, y, w, h, sx, sy, sw, sh, virtual)
function c:respectHierarchy(bool) hierarchy = bool end function c:respectHierarchy(bool) hierarchy = bool end
function c:OnUpdate(func) -- Not crazy about this approach, will probably rework this
if type(self) == "function" then func = self end
mainupdater(function() func(c) end)
end
local function centerthread() local function centerthread()
local centerfunc = function() local centerfunc = function()
return centerX or centerY -- If the condition is true it acts like a yield return centerX or centerY -- If the condition is true it acts like a yield
@ -1488,7 +1488,6 @@ local processors = {
gui.draw = drawer.run gui.draw = drawer.run
gui.update = function() gui.update = function()
for i = 1, #processors do for i = 1, #processors do
print(i)
processors[i]() processors[i]()
end end
end end