Working on advanced gui elements

This commit is contained in:
Ryan Ward 2023-12-19 01:48:01 -05:00
parent ffd3f24d05
commit 869db0c347
6 changed files with 219 additions and 38 deletions

0
addons/init.lua Normal file
View File

View File

@ -1,4 +1,5 @@
local gui = require("gui")
local theme = require("gui.core.theme")
local default_theme = theme:new("64342e", "b2989e", "909b9a")
function gui:newWindow(x, y, w, h, text, draggable)

0
core/init.lua Normal file
View File

69
elements/init.lua Normal file
View File

@ -0,0 +1,69 @@
local gui = require("gui")
local color = require("gui.core.color")
local theme = require("gui.core.theme")
local transition = require("gui.elements.transitions")
function gui:newMenu(title, sx, position, trans)
if not title then multi.error("Argument 1 string('title') is required") end
if not sx then multi.error("Argument 2 number('sx') is required") end
local position = position or gui.ALIGN_LEFT
local trans = trans or transition.glide
local menu, to, tc, open
if position == gui.ALIGN_LEFT then
menu = self:newFrame(0, 0, 0, 0, -sx, 0, sx, 1)
to = trans(-sx, 0, .25)
tc = trans(0, -sx, .25)
elseif position == gui.ALIGN_CENTER then
menu = self:newFrame(0, 0, 0, 0, .5 -sx/2, 1.1, sx, 1)
to = trans(1.1, 0, .35)
tc = trans(0, 1.1, .35)
elseif position == gui.ALIGN_RIGHT then
menu = self:newFrame(0, 0, 0, 0, 1, 0, sx, 1)
to = trans(1, 1 - sx, .25)
tc = trans(1 - sx, 1, .25)
end
function menu:isOpen()
return open
end
function menu:Open(show)
if show then
if not menu.lock then
menu.lock = true
local t = to()
t.OnStop(function()
open = true
menu.lock = false
end)
t.OnStep(function(p)
if position == gui.ALIGN_CENTER then
menu:setDualDim(nil, nil, nil, nil, nil, p)
else
menu:setDualDim(nil, nil, nil, nil, p)
end
end)
end
else
if not menu.lock then
menu.lock = true
local t = tc()
t.OnStop(function()
open = false
menu.lock = false
end)
t.OnStep(function(p)
if position == gui.ALIGN_CENTER then
menu:setDualDim(nil, nil, nil, nil, nil, p)
else
menu:setDualDim(nil, nil, nil, nil, p)
end
end)
end
end
end
return menu
end

56
elements/transitions.lua Normal file
View File

@ -0,0 +1,56 @@
local gui = require("gui")
local multi, thread = require("multi"):init()
local processor = gui:newProcessor("Transistion Processor")
local transition = {}
local width, height, flags = love.window.getMode()
local fps = 60
if flags.refreshrate > 0 then
fps = flags.refreshrate
end
transition.__index = transition
transition.__call = function(t, start, stop, time, ...)
local args = {...}
return function()
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
local handle = t.func(t, start, stop, time or 1, unpack(args))
return {
OnStep = handle.OnStatus,
OnStop = handle.OnReturn + handle.OnError
}
end
end
function transition:newTransition(func)
local c = {}
setmetatable(c, self)
c.fps = fps
c.func = processor:newFunction(func)
c.OnStop = multi:newConnection()
function c:SetFPS(fps)
self.fps = fps
end
function c:GetFPS(fps)
return self.fps
end
return c
end
transition.glide = transition:newTransition(function(t, start, stop, time, ...)
local steps = t.fps*time
local piece = time/steps
local split = stop-start
for i = 0, steps do
thread.sleep(piece)
thread.pushStatus(start + i*(split/steps))
end
end)
return transition

131
init.lua
View File

@ -4,7 +4,9 @@ local GLOBAL, THREAD = require("multi.integration.loveManager"):init()
local color = require("gui.core.color")
local gui = {}
local updater = multi:newProcessor("UpdateManager", true)
local drawer = multi:newProcessor("DrawManager", true)
local bit = require("bit")
local band, bor = bit.band, bit.bor
local cursor_hand = love.mouse.getSystemCursor("hand")
@ -176,6 +178,10 @@ gui.HotKeys.OnRedo = gui:setHotKey({"lctrl", "y"}) +
-- Utils
gui.newFunction = updater.newFunction
function gui:getProcessor() return updater end
function gui:getObjectFocus() return object_focus end
function gui:hasType(t) return band(self.type, t) == t end
@ -376,8 +382,7 @@ function gui:clone(opt)
connections: Do we copy connections? (true/false)
}
]]
-- DO = {[[setImage]], c.image or IMAGE}
-- Connections are used greatly throughout do we copy those
local temp
local u = self:getUniques()
if self.type == frame then
@ -389,9 +394,9 @@ function gui:clone(opt)
elseif self.type == text then
temp = gui:newTextLabel(self.text, self:getDualDim())
elseif self.type == image + button then
temp = gui:newImageButton(u.DO[2], self:getDualDim())
temp = gui:newImageButton(u.Do[2], self:getDualDim())
elseif self.type == image then
temp = gui:newImageLabel(u.DO[2], self:getDualDim())
temp = gui:newImageLabel(u.Do[2], self:getDualDim())
else -- We are dealing with a complex object
temp = processDo(u)
end
@ -404,7 +409,7 @@ function gui:clone(opt)
if opt.connections then
conn = true
for i, v in pairs(self) do
if v.Type == "connector" then
if type(v) == "table" and v.Type == "connector" then
-- We want to copy the connection functions from the original object and bind them to the new one
if not temp[i] then
-- Incase we are dealing with a custom object, create a connection if the custom objects unique declearation didn't
@ -436,6 +441,7 @@ function gui:getUniques(tab)
visibility = self.visibility,
color = self.color,
borderColor = self.borderColor,
drawBorder = self.drawborder,
rotation = self.rotation
}
@ -480,6 +486,7 @@ function gui:newBase(typ, x, y, w, h, sx, sy, sw, sh, virtual)
c.visibility = 1
c.color = {.6, .6, .6}
c.borderColor = color.black
c.drawBorder = true
c.rotation = 0
c.OnLoad = multi:newConnection()
@ -1170,7 +1177,7 @@ end
-- Video
function gui:newVideo(source, x, y, w, h, sx, sy, sw, sh)
local c = self:newImageBase(video, x, y, w, h, sx, sy, sw, sh)
local c = self:newImageBase(video, x, y, w, h, sx, sy, sw, sh)
c.OnVideoFinished = multi:newConnection()
c.playing = false
@ -1310,7 +1317,7 @@ local drawtypes = {
end
}
local draw_handler = function(child)
local draw_handler = function(child, no_draw)
local bg = child.color
local bbg = child.borderColor
local ctype = child.type
@ -1324,6 +1331,8 @@ local draw_handler = function(child)
child.w = w
child.h = h
if no_draw then return end
if child.clipDescendants then
local children = child:getAllChildren()
for c = 1, #children do -- Tell the children to clip themselves
@ -1342,42 +1351,46 @@ local draw_handler = function(child)
elseif type(roundness) == "string" then
love.graphics.setScissor(x - 1, y - 2, w + 2, h + 3)
end
local drawB = child.drawBorder
-- Set color
love.graphics.setLineStyle("smooth")
love.graphics.setLineWidth(3)
love.graphics.setColor(bbg[1], bbg[2], bbg[3], vis)
love.graphics.rectangle("line", x, y, w, h, rx, ry, segments)
if drawB then
love.graphics.setColor(bbg[1], bbg[2], bbg[3], vis)
love.graphics.rectangle("line", x, y, w, h, rx, ry, segments)
end
love.graphics.setColor(bg[1], bg[2], bg[3], vis)
love.graphics.rectangle("fill", x, y, w, h, rx, ry, segments)
if drawB then
if roundness == "top" then
love.graphics.rectangle("fill", x, y + ry / 2, w, h - ry / 2 + 1)
love.graphics.setLineStyle("rough")
love.graphics.setColor(bbg[1], bbg[2], bbg[3], 1)
love.graphics.setLineWidth(1)
love.graphics.line(x, y + ry, x, y + h + 1, x + 1 + w, y + h + 1,
x + 1 + w, y + ry)
love.graphics.line(x, y + h, x + 1 + w, y + h)
love.graphics.setScissor()
love.graphics.setColor(bbg[1], bbg[2], bbg[3], .6)
love.graphics.line(x - 1, y + ry / 2 + 2, x - 1, y + h + 2)
love.graphics.line(x + w + 2, y + ry / 2 + 2, x + w + 2, y + h + 2)
elseif roundness == "bottom" then
love.graphics.rectangle("fill", x, y, w, h - ry + 2)
love.graphics.setLineStyle("rough")
love.graphics.setColor(bbg[1], bbg[2], bbg[3], 1)
love.graphics.setLineWidth(2)
love.graphics.line(x - 1, y + ry + 1, x - 1, y - 1, x + w + 1, y - 1,
x + w + 1, y + ry + 1)
love.graphics.setScissor()
love.graphics.line(x - 1, y - 1, x + w + 1, y - 1)
if roundness == "top" then
love.graphics.rectangle("fill", x, y + ry / 2, w, h - ry / 2 + 1)
love.graphics.setLineStyle("rough")
love.graphics.setColor(bbg[1], bbg[2], bbg[3], 1)
love.graphics.setLineWidth(1)
love.graphics.line(x, y + ry, x, y + h + 1, x + 1 + w, y + h + 1,
x + 1 + w, y + ry)
love.graphics.line(x, y + h, x + 1 + w, y + h)
love.graphics.setScissor()
love.graphics.setColor(bbg[1], bbg[2], bbg[3], .6)
love.graphics.line(x - 1, y + ry / 2 + 2, x - 1, y + h + 2)
love.graphics.line(x + w + 2, y + ry / 2 + 2, x + w + 2, y + h + 2)
elseif roundness == "bottom" then
love.graphics.rectangle("fill", x, y, w, h - ry + 2)
love.graphics.setLineStyle("rough")
love.graphics.setColor(bbg[1], bbg[2], bbg[3], 1)
love.graphics.setLineWidth(2)
love.graphics.line(x - 1, y + ry + 1, x - 1, y - 1, x + w + 1, y - 1,
x + w + 1, y + ry + 1)
love.graphics.setScissor()
love.graphics.line(x - 1, y - 1, x + w + 1, y - 1)
love.graphics.setColor(bbg[1], bbg[2], bbg[3], .6)
love.graphics.setLineWidth(2)
love.graphics.line(x - 1, y + 2, x - 1, y + h - 4 - ry / 2)
love.graphics.line(x + w + 1, y + 2, x + w + 1, y + h - 4 - ry / 2)
love.graphics.setColor(bbg[1], bbg[2], bbg[3], .6)
love.graphics.setLineWidth(2)
love.graphics.line(x - 1, y + 2, x - 1, y + h - 4 - ry / 2)
love.graphics.line(x + w + 1, y + 2, x + w + 1, y + h - 4 - ry / 2)
end
end
-- Start object specific stuff
@ -1406,9 +1419,39 @@ drawer:newLoop(function()
first_loop = true
end)
drawer:newThread(function()
while true do
thread.sleep(.01)
local children = gui.virtual: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)
local processors = {
updater.run
}
-- Drawing and Updating
gui.draw = drawer.run
gui.update = updater.run
gui.update = function()
for i = 1, #processors do
processors[i]()
end
end
function gui:newProcessor(name)
local proc = multi:newProcessor(name or "UnNamedProcess_"..multi.randomString(8), true)
table.insert(processors, proc.run)
return proc
end
-- Virtual gui
gui.virtual.type = frame
@ -1475,11 +1518,23 @@ gui.Events.OnResized(function(w, h)
gui.dualDim.offset.size.y = nh
gui.w = nw
gui.h = nh
gui.virtual.x = xt
gui.virtual.y = yt
gui.virtual.dualDim.offset.size.x = nw
gui.virtual.dualDim.offset.size.y = nh
gui.virtual.w = nw
gui.virtual.h = nh
else
gui.dualDim.offset.size.x = w
gui.dualDim.offset.size.y = h
gui.w = w
gui.h = h
gui.virtual.dualDim.offset.size.x = w
gui.virtual.dualDim.offset.size.y = h
gui.virtual.w = w
gui.virtual.h = h
end
end)