Woring on features
This commit is contained in:
parent
a68966879d
commit
d1f1d79c76
0
addons/init.lua
Normal file
0
addons/init.lua
Normal 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)
|
||||
|
||||
26
core/canvas.lua
Normal file
26
core/canvas.lua
Normal file
@ -0,0 +1,26 @@
|
||||
local gui = require("gui")
|
||||
|
||||
function newCanvas(domain)
|
||||
local c
|
||||
if domain == "visual" then
|
||||
c = gui:newVisualFrame()
|
||||
else
|
||||
c = gui:newVirtualFrame()
|
||||
end
|
||||
c:fullFrame()
|
||||
function c:swap(c1, c2)
|
||||
local temp = c1.children
|
||||
c1.children = c2.children
|
||||
c2.children = temp
|
||||
for i,v in pairs(c1.children) do
|
||||
v.parent = c1
|
||||
end
|
||||
for i,v in pairs(c2.children) do
|
||||
v.parent = c2
|
||||
end
|
||||
end
|
||||
|
||||
return c
|
||||
end
|
||||
|
||||
return newCanvas
|
||||
@ -47,7 +47,7 @@ function color.hsl(h, s, l)
|
||||
elseif h < 4 then r,b,g = 0,x,c
|
||||
elseif h < 5 then r,b,g = x,0,c
|
||||
else r,b,g = c,0,x
|
||||
end return (r+m)*255, (g+m)*255, (b+m)*255
|
||||
end return (r+m)*255, (g+m)*255, (b+m)*255, 255
|
||||
end
|
||||
|
||||
min = math.min
|
||||
@ -60,7 +60,7 @@ function color.hsv(h, s, v)
|
||||
local r = min (max (3*abs (((h )/180)%2-1)-1, 0), 1)
|
||||
local g = min (max (3*abs (((h -120)/180)%2-1)-1, 0), 1)
|
||||
local b = min (max (3*abs (((h +120)/180)%2-1)-1, 0), 1)
|
||||
return k1 + k2 * r, k1 + k2 * g, k1 + k2 * b
|
||||
return k1 + k2 * r, k1 + k2 * g, k1 + k2 * b, 1
|
||||
end
|
||||
|
||||
function color.isLight(r, g, b)
|
||||
@ -102,9 +102,10 @@ function color.new(r, g, b, fmt)
|
||||
end
|
||||
local temp
|
||||
if fmt then
|
||||
temp = {r,b,g}
|
||||
temp = {r, b, g, 1}
|
||||
else
|
||||
temp = {love.math.colorFromBytes(r, g, b)}
|
||||
temp[4] = 1
|
||||
end
|
||||
setmetatable(temp, mt)
|
||||
return temp
|
||||
|
||||
90
core/simulate.lua
Normal file
90
core/simulate.lua
Normal file
@ -0,0 +1,90 @@
|
||||
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 = {}
|
||||
|
||||
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
|
||||
love.mouse.setPosition(x, y)
|
||||
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
|
||||
love.mouse.setPosition(x, y)
|
||||
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
|
||||
love.mouse.setPosition(x, y)
|
||||
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
|
||||
|
||||
if dx == 0 and dy == 0 then
|
||||
_x, _y = love.mouse.getPosition()
|
||||
if x == _x and y == _y then
|
||||
return
|
||||
end
|
||||
local dx, dy = 0, 0
|
||||
dx = x - _x
|
||||
dy = y - _y
|
||||
return simulate.Move(nil, dx, dy)
|
||||
end
|
||||
gui.Events.OnMouseMoved:Fire(x, y, 0, 0, istouch or false)
|
||||
thread.skip(1)
|
||||
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()
|
||||
love.mouse.setPosition(x + p, _y)
|
||||
end)
|
||||
local yy = gy()
|
||||
yy.OnStep(function(p)
|
||||
_x, _y = love.mouse.getPosition()
|
||||
love.mouse.setPosition(_x, y + p)
|
||||
end)
|
||||
if not(dx==0 and dy == 0) then
|
||||
thread.hold(xx.OnStop * yy.OnStop)
|
||||
end
|
||||
gui.Events.OnMouseMoved:Fire(x + dx, y + dy, 0, 0, istouch or false)
|
||||
end, true)
|
||||
|
||||
return simulate
|
||||
@ -47,7 +47,6 @@ function theme:random(seed, lightness, rand)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
t.seed = seed
|
||||
return t
|
||||
end
|
||||
|
||||
104
elements/init.lua
Normal file
104
elements/init.lua
Normal file
@ -0,0 +1,104 @@
|
||||
local gui = require("gui")
|
||||
local color = require("gui.core.color")
|
||||
local theme = require("gui.core.theme")
|
||||
local transition = require("gui.elements.transitions")
|
||||
local processor = gui:newProcessor("menu")
|
||||
|
||||
function gui:newMenu(title, sx, position, trans, callback, t,t2)
|
||||
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
|
||||
if callback then if not type(callback) == "function" then multi.error("Argument 5 function('callback(menu(self),align[left,center,right],transition_position)') must be a function") end end
|
||||
local t = t or .35
|
||||
local t2 = t2 or .25
|
||||
local position = position or gui.ALIGN_LEFT
|
||||
local trans = trans or transition.glide
|
||||
|
||||
local menu, to, tc, open
|
||||
if callback then
|
||||
menu = self:newFrame(0, 0, 0, 0, .5 -sx/2, 1, sx, 1)
|
||||
to = trans(1, 0, t)
|
||||
tc = trans(0, 1, t)
|
||||
else
|
||||
if position == gui.ALIGN_LEFT then
|
||||
menu = self:newFrame(0, 0, 0, 0, -sx, 0, sx, 1)
|
||||
to = trans(-sx, 0, t2)
|
||||
tc = trans(0, -sx, t2)
|
||||
elseif position == gui.ALIGN_CENTER then
|
||||
menu = self:newFrame(0, 0, 0, 0, .5 -sx/2, 1, sx, 1)
|
||||
to = trans(1, 0, t)
|
||||
tc = trans(0, 1, t)
|
||||
elseif position == gui.ALIGN_RIGHT then
|
||||
menu = self:newFrame(0, 0, 0, 0, 1, 0, sx, 1)
|
||||
to = trans(1, 1 - sx, t2)
|
||||
tc = trans(1 - sx, 1, t2)
|
||||
end
|
||||
end
|
||||
|
||||
function menu:isOpen()
|
||||
return open
|
||||
end
|
||||
|
||||
function menu:Open(show)
|
||||
if show then
|
||||
if not menu.lock then
|
||||
menu.visible = true
|
||||
menu.lock = true
|
||||
local t = to()
|
||||
t.OnStop(function()
|
||||
open = true
|
||||
menu.lock = false
|
||||
end)
|
||||
t.OnStep(function(p)
|
||||
if callback then
|
||||
callback(menu,position,p,"open")
|
||||
for i,v in pairs(menu:getAllChildren()) do
|
||||
callback(v,position,p,"open")
|
||||
end
|
||||
else
|
||||
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
|
||||
else
|
||||
if not menu.lock then
|
||||
menu.lock = true
|
||||
local t = tc()
|
||||
t.OnStop(function()
|
||||
open = false
|
||||
menu.lock = false
|
||||
menu.visible = false
|
||||
end)
|
||||
t.OnStep(function(p)
|
||||
if callback then
|
||||
callback(menu,position,p,"open")
|
||||
for i,v in pairs(menu:getAllChildren()) do
|
||||
callback(v,position,p,"open")
|
||||
end
|
||||
else
|
||||
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
|
||||
end
|
||||
|
||||
menu.OnCreate = processor:newConnection()
|
||||
local items = {}
|
||||
function menu:addItem(text)
|
||||
local item = menu:newTextButton(text,0,100*#items,0,100,0,0,1)
|
||||
items[#items+1] = item
|
||||
item:fitFont()
|
||||
item.align = gui.ALIGN_CENTER
|
||||
self.OnCreate:Fire(self,item,items)
|
||||
end
|
||||
|
||||
return menu
|
||||
end
|
||||
65
elements/transitions.lua
Normal file
65
elements/transitions.lua
Normal file
@ -0,0 +1,65 @@
|
||||
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
|
||||
local temp = {
|
||||
OnStep = function() end,
|
||||
OnStop = multi:newConnection()
|
||||
}
|
||||
proc:newTask(function()
|
||||
temp.OnStop:Fire()
|
||||
end)
|
||||
return temp
|
||||
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
|
||||
542
init.lua
542
init.lua
@ -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")
|
||||
@ -16,6 +18,8 @@ local global_drag
|
||||
local object_focus = gui
|
||||
local first_loop = false
|
||||
|
||||
gui.Version = "0.1.0"
|
||||
|
||||
-- Types
|
||||
gui.TYPE_FRAME = frame
|
||||
gui.TYPE_IMAGE = image
|
||||
@ -25,7 +29,7 @@ gui.TYPE_VIDEO = video
|
||||
gui.TYPE_BUTTON = button
|
||||
gui.TYPE_ANIM = anim
|
||||
|
||||
--
|
||||
-- Variables
|
||||
|
||||
gui.__index = gui
|
||||
gui.MOUSE_PRIMARY = 1
|
||||
@ -58,6 +62,16 @@ gui.Events.OnTouchMoved = multi:newConnection()
|
||||
gui.Events.OnTouchPressed = multi:newConnection()
|
||||
gui.Events.OnTouchReleased = multi:newConnection()
|
||||
|
||||
-- Joysticks and gamepads
|
||||
gui.Events.OnGamepadPressed = multi:newConnection()
|
||||
gui.Events.OnGamepadReleased = multi:newConnection()
|
||||
gui.Events.OnGamepadAxis = multi:newConnection()
|
||||
gui.Events.OnJoystickAdded = multi:newConnection()
|
||||
gui.Events.OnJoystickHat = multi:newConnection()
|
||||
gui.Events.OnJoystickPressed = multi:newConnection()
|
||||
gui.Events.OnJoystickReleased = multi:newConnection()
|
||||
gui.Events.OnJoystickRemoved = multi:newConnection()
|
||||
|
||||
-- Non Love Events
|
||||
|
||||
gui.Events.OnThemeChanged = multi:newConnection()
|
||||
@ -82,27 +96,44 @@ local function Hook(funcname, func)
|
||||
end
|
||||
end
|
||||
|
||||
-- This will run the hooks after everything has loaded
|
||||
-- Incase you define one of these methods, we need to process this after that
|
||||
updater:newTask(function()
|
||||
-- System
|
||||
Hook("quit", gui.Events.OnQuit.Fire)
|
||||
Hook("directorydropped", gui.Events.OnDirectoryDropped.Fire)
|
||||
Hook("displayrotated", gui.Events.OnDisplayRotated.Fire)
|
||||
Hook("filedropped", gui.Events.OnFilesDropped.Fire)
|
||||
Hook("focus", gui.Events.OnFocus.Fire)
|
||||
Hook("mousefocus", gui.Events.OnMouseFocus.Fire)
|
||||
Hook("resize", gui.Events.OnResized.Fire)
|
||||
Hook("visible", gui.Events.OnVisible.Fire)
|
||||
|
||||
-- Mouse
|
||||
Hook("mousefocus", gui.Events.OnMouseFocus.Fire)
|
||||
Hook("keypressed", gui.Events.OnKeyPressed.Fire)
|
||||
Hook("keyreleased", gui.Events.OnKeyReleased.Fire)
|
||||
Hook("textedited", gui.Events.OnTextEdited.Fire)
|
||||
Hook("textinput", gui.Events.OnTextInputed.Fire)
|
||||
Hook("mousemoved", gui.Events.OnMouseMoved.Fire)
|
||||
Hook("mousepressed", gui.Events.OnMousePressed.Fire)
|
||||
Hook("mousereleased", gui.Events.OnMouseReleased.Fire)
|
||||
Hook("wheelmoved", gui.Events.OnWheelMoved.Fire)
|
||||
|
||||
-- Keyboard
|
||||
Hook("textedited", gui.Events.OnTextEdited.Fire)
|
||||
Hook("textinput", gui.Events.OnTextInputed.Fire)
|
||||
|
||||
-- Touchscreen
|
||||
Hook("touchmoved", gui.Events.OnTouchMoved.Fire)
|
||||
Hook("touchpressed", gui.Events.OnTouchPressed.Fire)
|
||||
Hook("touchreleased", gui.Events.OnTouchReleased.Fire)
|
||||
|
||||
-- Joystick/Gamepad
|
||||
Hook("gamepadpressed", gui.Events.OnGamepadPressed.Fire)
|
||||
Hook("gamepadaxis", gui.Events.OnGamepadAxis.Fire)
|
||||
Hook("gamepadreleased", gui.Events.OnGamepadReleased.Fire)
|
||||
Hook("joystickpressed", gui.Events.OnJoystickPressed.Fire)
|
||||
Hook("joystickreleased", gui.Events.OnJoystickReleased.Fire)
|
||||
Hook("joystickhat", gui.Events.OnJoystickHat.Fire)
|
||||
Hook("joystickremoved", gui.Events.OnJoystickRemoved.Fire)
|
||||
Hook("joystickadded", gui.Events.OnJoystickAdded.Fire)
|
||||
end)
|
||||
|
||||
-- Hotkeys
|
||||
@ -179,6 +210,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
|
||||
@ -186,6 +221,7 @@ function gui:hasType(t) return band(self.type, t) == t end
|
||||
function gui:move(x, y)
|
||||
self.dualDim.offset.pos.x = self.dualDim.offset.pos.x + x
|
||||
self.dualDim.offset.pos.y = self.dualDim.offset.pos.y + y
|
||||
self.OnPositionChanged:Fire(self, x, y)
|
||||
end
|
||||
|
||||
function gui:moveInBounds(dx, dy)
|
||||
@ -237,7 +273,29 @@ end
|
||||
|
||||
function gui:getChildren() return self.children end
|
||||
|
||||
function gui:getAbsolutes() -- returns x, y, w, h
|
||||
function gui:offsetToScale()
|
||||
local children = self:getAllChildren()
|
||||
for i = 1, #children do
|
||||
local child = children[i]
|
||||
local x, y = child:getAbsolutes()
|
||||
local _, __, w, h = child.parent:getAbsolutes()
|
||||
print(x / w, y / h)
|
||||
local _, __, w, h = child:getAbsolutes()
|
||||
local _, __, pw, ph = child.parent:getAbsolutes()
|
||||
print(w / pw, h / ph)
|
||||
end
|
||||
end
|
||||
|
||||
function gui:getAbsolutes(transform) -- returns x, y, w, h
|
||||
if transform then
|
||||
return transform((self.parent.w * self.dualDim.scale.pos.x) +
|
||||
self.dualDim.offset.pos.x + self.parent.x),
|
||||
transform((self.parent.h * self.dualDim.scale.pos.y) +
|
||||
self.dualDim.offset.pos.y + self.parent.y), transform((self.parent.w *
|
||||
self.dualDim.scale.size.x) + self.dualDim.offset.size.x),
|
||||
transform((self.parent.h * self.dualDim.scale.size.y) +
|
||||
self.dualDim.offset.size.y)
|
||||
else
|
||||
return (self.parent.w * self.dualDim.scale.pos.x) +
|
||||
self.dualDim.offset.pos.x + self.parent.x,
|
||||
(self.parent.h * self.dualDim.scale.pos.y) +
|
||||
@ -245,6 +303,7 @@ function gui:getAbsolutes() -- returns x, y, w, h
|
||||
self.dualDim.scale.size.x) + self.dualDim.offset.size.x,
|
||||
(self.parent.h * self.dualDim.scale.size.y) +
|
||||
self.dualDim.offset.size.y
|
||||
end
|
||||
end
|
||||
|
||||
function gui:getAllChildren(vis)
|
||||
@ -263,31 +322,38 @@ function gui:getAllChildren(vis)
|
||||
end
|
||||
|
||||
function gui:newThread(func)
|
||||
return updater:newThread("ThreadHandler<" .. self.type .. ">", func, self,
|
||||
thread)
|
||||
return updater:newThread("ThreadHandler<" .. self.type .. ">", func, self, thread)
|
||||
end
|
||||
|
||||
function gui:setDualDim(x, y, w, h, sx, sy, sw, sh)
|
||||
self.dualDim.offset = {
|
||||
pos = {
|
||||
x = x or self.dualDim.offset.pos.x,
|
||||
y = y or self.dualDim.offset.pos.y
|
||||
},
|
||||
size = {
|
||||
x = w or self.dualDim.offset.size.x,
|
||||
y = h or self.dualDim.offset.size.y
|
||||
}
|
||||
}
|
||||
self.dualDim.scale = {
|
||||
pos = {
|
||||
x = sx or self.dualDim.scale.pos.x,
|
||||
y = sy or self.dualDim.scale.pos.y
|
||||
},
|
||||
size = {
|
||||
x = sw or self.dualDim.scale.size.x,
|
||||
y = sh or self.dualDim.scale.size.y
|
||||
}
|
||||
}
|
||||
--[[
|
||||
dd.offset.pos = {x = x or 0, y = y or 0}
|
||||
self.dualDim.offset.size = {x = w or 0, y = h or 0}
|
||||
self.dualDim.scale.pos = {x = sx or 0, y = sy or 0}
|
||||
self.dualDim.scale.size = {x = sw or 0, y = sh or 0}
|
||||
]]
|
||||
self.dualDim = self:newDualDim(
|
||||
x or self.dualDim.offset.pos.x,
|
||||
y or self.dualDim.offset.pos.y,
|
||||
w or self.dualDim.offset.size.x,
|
||||
h or self.dualDim.offset.size.y,
|
||||
sx or self.dualDim.scale.pos.x,
|
||||
sy or self.dualDim.scale.pos.y,
|
||||
sw or self.dualDim.scale.size.x,
|
||||
sh or self.dualDim.scale.size.y)
|
||||
self.OnSizeChanged:Fire(self, x, y, w, h, sx, sy, sw, sh)
|
||||
end
|
||||
|
||||
function gui:rawSetDualDim(x, y, w, h, sx, sy, sw, sh)
|
||||
self.dualDim = self:newDualDim(
|
||||
x or self.dualDim.offset.pos.x,
|
||||
y or self.dualDim.offset.pos.y,
|
||||
w or self.dualDim.offset.size.x,
|
||||
h or self.dualDim.offset.size.y,
|
||||
sx or self.dualDim.scale.pos.x,
|
||||
sy or self.dualDim.scale.pos.y,
|
||||
sw or self.dualDim.scale.size.x,
|
||||
sh or self.dualDim.scale.size.y)
|
||||
end
|
||||
|
||||
local image_cache = {}
|
||||
@ -332,6 +398,11 @@ end
|
||||
|
||||
local mainupdater = updater:newLoop().OnLoop
|
||||
|
||||
function gui:OnUpdate(func) -- Not crazy about this approach, will probably rework this
|
||||
if type(self) == "function" then func = self end
|
||||
mainupdater(function() func(self) end)
|
||||
end
|
||||
|
||||
function gui:canPress(mx, my) -- Get the intersection of the clip area and the self then test with the clip, otherwise test as normal
|
||||
local x, y, w, h
|
||||
if self.__variables.clip[1] then
|
||||
@ -385,8 +456,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
|
||||
@ -398,9 +468,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
|
||||
@ -413,7 +483,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
|
||||
@ -437,6 +507,11 @@ function gui:isActive()
|
||||
return self.active and not (self:isDescendantOf(gui.virtual))
|
||||
end
|
||||
|
||||
function gui:isOnScreen()
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
-- Base get uniques
|
||||
function gui:getUniques(tab)
|
||||
local base = {
|
||||
@ -445,6 +520,7 @@ function gui:getUniques(tab)
|
||||
visibility = self.visibility,
|
||||
color = self.color,
|
||||
borderColor = self.borderColor,
|
||||
drawBorder = self.drawborder,
|
||||
rotation = self.rotation
|
||||
}
|
||||
|
||||
@ -452,9 +528,32 @@ function gui:getUniques(tab)
|
||||
return base
|
||||
end
|
||||
|
||||
function gui:setTag(tag)
|
||||
self.tags[tag] = true
|
||||
end
|
||||
|
||||
function gui:hasTag(tag)
|
||||
return self.tags[tag]
|
||||
end
|
||||
|
||||
function gui:parentHasTag(tag)
|
||||
local parent = self.parent
|
||||
while parent do
|
||||
if parent.tags and parent.tags[tag] then return true end
|
||||
parent = parent.parent
|
||||
if parent == gui.virtual or parent == gui then return false end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function testVisual(c, x, y, button, istouch, presses)
|
||||
return not(c:hasTag("visual") or c:parentHasTag("visual"))
|
||||
end
|
||||
|
||||
-- Base Library
|
||||
function gui:newBase(typ, x, y, w, h, sx, sy, sw, sh, virtual)
|
||||
local c = {}
|
||||
c.tags = {}
|
||||
local buildBackBetter
|
||||
local centerX = false
|
||||
local centerY = false
|
||||
@ -470,8 +569,19 @@ function gui:newBase(typ, x, y, w, h, sx, sy, sw, sh, virtual)
|
||||
return true
|
||||
end
|
||||
|
||||
setmetatable(c, gui)
|
||||
local function defaultCheck(...)
|
||||
if not c:isActive() then return false end
|
||||
local x, y = love.mouse.getPosition()
|
||||
if c:canPress(x, y) then
|
||||
return c, ...
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
setmetatable(c, self)
|
||||
c.__index = self.__index
|
||||
c.__variables = {clip = {false, 0, 0, 0, 0}}
|
||||
c.focus = false
|
||||
c.active = true
|
||||
c.type = typ
|
||||
c.dualDim = self:newDualDim(x, y, w, h, sx, sy, sw, sh)
|
||||
@ -480,22 +590,38 @@ 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.OnPressed = testHierarchy .. multi:newConnection()
|
||||
c.OnPressedOuter = multi:newConnection()
|
||||
c.OnReleased = testHierarchy .. multi:newConnection()
|
||||
c.OnReleasedOuter = multi:newConnection()
|
||||
c.OnReleasedOther = multi:newConnection()
|
||||
c.OnLoad = multi:newConnection()
|
||||
|
||||
c.OnDragStart = multi:newConnection()
|
||||
c.OnDragging = multi:newConnection()
|
||||
c.OnDragEnd = multi:newConnection()
|
||||
c.OnPressed = testVisual .. (testHierarchy .. multi:newConnection())
|
||||
c.OnPressedOuter = testVisual .. multi:newConnection()
|
||||
c.OnReleased = testVisual .. (testHierarchy .. multi:newConnection())
|
||||
c.OnReleasedOuter = testVisual .. multi:newConnection()
|
||||
c.OnReleasedOther = testVisual .. multi:newConnection()
|
||||
|
||||
c.OnEnter = testHierarchy .. multi:newConnection()
|
||||
c.OnExit = multi:newConnection()
|
||||
c.OnDragStart = testVisual .. multi:newConnection()
|
||||
c.OnDragging = testVisual .. multi:newConnection()
|
||||
c.OnDragEnd = testVisual .. multi:newConnection()
|
||||
|
||||
c.OnMoved = testHierarchy .. multi:newConnection()
|
||||
c.OnEnter = (testHierarchy .. multi:newConnection())
|
||||
c.OnExit = testVisual .. multi:newConnection()
|
||||
|
||||
c.OnMoved = testVisual .. (testHierarchy .. multi:newConnection())
|
||||
c.OnWheelMoved = testVisual .. (defaultCheck / gui.Events.OnWheelMoved)
|
||||
|
||||
c.OnSizeChanged = testVisual .. multi:newConnection()
|
||||
c.OnPositionChanged = testVisual .. multi:newConnection()
|
||||
|
||||
c.OnLeftStickUp = testVisual .. multi:newConnection()
|
||||
c.OnLeftStickDown = testVisual .. multi:newConnection()
|
||||
c.OnLeftStickLeft = testVisual .. multi:newConnection()
|
||||
c.OnLeftStickRight = testVisual .. multi:newConnection()
|
||||
c.OnRightStickUp = testVisual .. multi:newConnection()
|
||||
c.OnRightStickDown = testVisual .. multi:newConnection()
|
||||
c.OnRightStickLeft = testVisual .. multi:newConnection()
|
||||
c.OnRightStickRight = testVisual .. multi:newConnection()
|
||||
|
||||
local dragging = false
|
||||
local entered = false
|
||||
@ -522,7 +648,7 @@ function gui:newBase(typ, x, y, w, h, sx, sy, sw, sh, virtual)
|
||||
gui.Events.OnMouseReleased(function(x, y, button, istouch, presses)
|
||||
if not c:isActive() then return end
|
||||
if c:canPress(x, y) then
|
||||
c.OnReleased:Fire(c, x, y, dx, dy, istouch, presses)
|
||||
c.OnReleased:Fire(c, x, y, button, istouch, presses)
|
||||
elseif pressed then
|
||||
c.OnReleasedOuter:Fire(c, x, y, button, istouch, presses)
|
||||
else
|
||||
@ -559,6 +685,11 @@ function gui:newBase(typ, x, y, w, h, sx, sy, sw, sh, virtual)
|
||||
end
|
||||
end)
|
||||
|
||||
function c:isOffScreen()
|
||||
local x, y, w, h = self:getAbsolutes()
|
||||
return y + h < 0 or y > gui.h or x + w < 0 or x > gui.w
|
||||
end
|
||||
|
||||
function c:setRoundness(rx, ry, seg, side)
|
||||
self.roundness = side or true
|
||||
self.__rx, self.__ry, self.__segments = rx or 5, ry or 5, seg or 30
|
||||
@ -571,27 +702,16 @@ function gui:newBase(typ, x, y, w, h, sx, sy, sw, sh, virtual)
|
||||
|
||||
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 centerfunc = function()
|
||||
return centerX or centerY -- If the condition is true it acts like a yield
|
||||
end
|
||||
c:newThread(function()
|
||||
while true do
|
||||
thread.hold(centerfunc)
|
||||
if centerX or centerY then
|
||||
local x, y, w, h = c:getAbsolutes()
|
||||
if centerX then
|
||||
c:setDualDim(-w / 2, nil, nil, nil, .5)
|
||||
c:rawSetDualDim(-w / 2, nil, nil, nil, .5)
|
||||
end
|
||||
if centerY then
|
||||
c:setDualDim(nil, -h / 2, nil, nil, nil, .5)
|
||||
c:rawSetDualDim(nil, -h / 2, nil, nil, nil, .5)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function c:enableDragging(but)
|
||||
@ -607,14 +727,22 @@ function gui:newBase(typ, x, y, w, h, sx, sy, sw, sh, virtual)
|
||||
centerX = bool
|
||||
if centering then return end
|
||||
centering = true
|
||||
centerthread()
|
||||
self.OnSizeChanged(centerthread)
|
||||
self.OnPositionChanged(centerthread)
|
||||
updater:newLoop(centerthread)
|
||||
end
|
||||
|
||||
function c:centerY(bool)
|
||||
centerY = bool
|
||||
if centering then return end
|
||||
centering = true
|
||||
centerthread()
|
||||
self.OnSizeChanged(centerthread)
|
||||
self.OnPositionChanged(centerthread)
|
||||
updater:newLoop(centerthread)
|
||||
end
|
||||
|
||||
function c:fullFrame()
|
||||
self:setDualDim(0,0,0,0,0,0,1,1)
|
||||
end
|
||||
|
||||
-- Add to the parents children table
|
||||
@ -625,6 +753,7 @@ function gui:newBase(typ, x, y, w, h, sx, sy, sw, sh, virtual)
|
||||
c.parent = self
|
||||
table.insert(self.children, c)
|
||||
end
|
||||
local a = 0
|
||||
return c
|
||||
end
|
||||
|
||||
@ -653,6 +782,13 @@ end
|
||||
function gui:newVirtualFrame(x, y, w, h, sx, sy, sw, sh)
|
||||
return self:newBase(frame, x, y, w, h, sx, sy, sw, sh, true)
|
||||
end
|
||||
|
||||
function gui:newVisualFrame(x, y, w, h, sx, sy, sw, sh)
|
||||
local visual = self:newBase(frame, x, y, w, h, sx, sy, sw, sh)
|
||||
visual:setTag("visual")
|
||||
return visual
|
||||
end
|
||||
|
||||
local testIMG
|
||||
-- Texts
|
||||
function gui:newTextBase(typ, txt, x, y, w, h, sx, sy, sw, sh)
|
||||
@ -669,7 +805,7 @@ function gui:newTextBase(typ, txt, x, y, w, h, sx, sy, sw, sh)
|
||||
c.textVisibility = 1
|
||||
c.font = love.graphics.newFont(12)
|
||||
c.textColor = color.black
|
||||
c.OnFontUpdated = multi:newConnection()
|
||||
c.OnFontUpdated = testVisual .. multi:newConnection()
|
||||
|
||||
function c:calculateFontOffset(font, adjust)
|
||||
local adjust = adjust or 20
|
||||
@ -716,7 +852,9 @@ function gui:newTextBase(typ, txt, x, y, w, h, sx, sy, sw, sh)
|
||||
end
|
||||
|
||||
function c:setFont(font, size)
|
||||
if type(font) == "string" then
|
||||
if type(font) == "number" then
|
||||
self.font = love.graphics.newFont(font)
|
||||
elseif type(font) == "string" then
|
||||
self.fontFile = font
|
||||
self.font = love.graphics.newFont(font, size)
|
||||
else
|
||||
@ -725,10 +863,8 @@ function gui:newTextBase(typ, txt, x, y, w, h, sx, sy, sw, sh)
|
||||
self.OnFontUpdated:Fire(self)
|
||||
end
|
||||
|
||||
function c:fitFont(n, max)
|
||||
local max = max or math.huge
|
||||
function c:fitFont(min_size, max_size)
|
||||
local font
|
||||
local isdefault = false
|
||||
if self.fontFile then
|
||||
if self.fontFile:match("ttf") then
|
||||
font = function(n)
|
||||
@ -740,26 +876,66 @@ function gui:newTextBase(typ, txt, x, y, w, h, sx, sy, sw, sh)
|
||||
end
|
||||
end
|
||||
else
|
||||
isdefault = true
|
||||
font = function(n) return love.graphics.setNewFont(n) end
|
||||
end
|
||||
local x, y, width, height = self:getAbsolutes()
|
||||
local Font, text = self.Font, self.text
|
||||
local s = 3
|
||||
Font = font(s)
|
||||
while height < max and Font:getHeight() < height and Font:getWidth(text) < width do
|
||||
s = s + 1
|
||||
Font = font(s)
|
||||
local text = self.text
|
||||
local x, y, max_width, max_height = self:getAbsolutes()
|
||||
local min_size = min_size or 1
|
||||
local max_size = max_size or 100 -- You can adjust the maximum font size as needed
|
||||
local tolerance = 0.1
|
||||
local f
|
||||
while max_size - min_size > tolerance do
|
||||
local size = (min_size + max_size) / 2
|
||||
|
||||
f = font(size)
|
||||
local text_width = f:getWidth(text)
|
||||
local text_height = f:getHeight()
|
||||
|
||||
if text_width > max_width or text_height > max_height then
|
||||
max_size = size
|
||||
else
|
||||
min_size = size
|
||||
end
|
||||
Font = font(s - (4 + (n or 0)))
|
||||
Font:setFilter("linear", "nearest", 4)
|
||||
self.font = Font
|
||||
self.textOffsetY = 0
|
||||
local top, bottom = self:calculateFontOffset(Font, 0)
|
||||
self.textOffsetY = floor(((height - bottom) - top) / 2)
|
||||
self.OnFontUpdated:Fire(self)
|
||||
return s - (4 + (n or 0))
|
||||
end
|
||||
self:setFont(f)
|
||||
return min_size
|
||||
end
|
||||
|
||||
-- function c:fitFont(n, max)
|
||||
-- local max = max or math.huge
|
||||
-- local font
|
||||
-- local isdefault = false
|
||||
-- if self.fontFile then
|
||||
-- if self.fontFile:match("ttf") then
|
||||
-- font = function(n)
|
||||
-- return love.graphics.newFont(self.fontFile, n, "normal")
|
||||
-- end
|
||||
-- else
|
||||
-- font = function(n)
|
||||
-- return love.graphics.newFont(self.fontFile, n)
|
||||
-- end
|
||||
-- end
|
||||
-- else
|
||||
-- isdefault = true
|
||||
-- font = function(n) return love.graphics.setNewFont(n) end
|
||||
-- end
|
||||
-- local x, y, width, height = self:getAbsolutes()
|
||||
-- local Font, text = self.Font, self.text
|
||||
-- local s = 3
|
||||
-- Font = font(s)
|
||||
-- while height < max and Font:getHeight() < height and Font:getWidth(text) < width do
|
||||
-- s = s + 1
|
||||
-- Font = font(s)
|
||||
-- end
|
||||
-- Font = font(s - (4 + (n or 0)))
|
||||
-- Font:setFilter("linear", "nearest", 4)
|
||||
-- self.font = Font
|
||||
-- self.textOffsetY = 0
|
||||
-- local top, bottom = self:calculateFontOffset(Font, 0)
|
||||
-- self.textOffsetY = floor(((height - bottom) - top) / 2)
|
||||
-- self.OnFontUpdated:Fire(self)
|
||||
-- return s - (4 + (n or 0))
|
||||
-- end
|
||||
|
||||
function c:centerFont()
|
||||
local x, y, width, height = self:getAbsolutes()
|
||||
@ -842,7 +1018,7 @@ function gui:newTextBox(txt, x, y, w, h, sx, sy, sw, sh)
|
||||
c:respectHierarchy(true)
|
||||
c.doSelection = false
|
||||
|
||||
c.OnReturn = multi:newConnection()
|
||||
c.OnReturn = testVisual .. multi:newConnection()
|
||||
|
||||
c.cur_pos = 0
|
||||
c.selection = {0, 0}
|
||||
@ -1027,12 +1203,12 @@ local load_images = THREAD:newFunction(function(paths)
|
||||
require("love.image")
|
||||
local images = #paths
|
||||
for i = 1, #paths do
|
||||
sThread.pushStatus(i, images, love.image.newImageData(paths[i]))
|
||||
_G.THREAD.pushStatus(i, images, love.image.newImageData(paths[i]))
|
||||
end
|
||||
end)
|
||||
|
||||
-- Loads a resource and adds it to the cache
|
||||
gui.cacheImage = thread:newFunction(function(self, path_or_paths)
|
||||
gui.cacheImage = updater:newFunction(function(self, path_or_paths)
|
||||
if type(path_or_paths) == "string" then
|
||||
-- runs thread to load image then cache it for faster loading
|
||||
load_image(path_or_paths).OnReturn(function(img)
|
||||
@ -1048,10 +1224,48 @@ gui.cacheImage = thread:newFunction(function(self, path_or_paths)
|
||||
end
|
||||
end)
|
||||
|
||||
function gui:applyGradient(direction, ...)
|
||||
local colors = {...}
|
||||
if direction == "horizontal" then
|
||||
direction = true
|
||||
elseif direction == "vertical" then
|
||||
direction = false
|
||||
else
|
||||
error("Invalid direction '" .. tostring(direction) .. "' for gradient. Horizontal or vertical expected.")
|
||||
end
|
||||
local result = love.image.newImageData(direction and 1 or #colors, direction and #colors or 1)
|
||||
for i, color in ipairs(colors) do
|
||||
local x, y
|
||||
if direction then
|
||||
x, y = 0, i - 1
|
||||
else
|
||||
x, y = i - 1, 0
|
||||
end
|
||||
result:setPixel(x, y, color[1], color[2], color[3], color[4] or 255)
|
||||
end
|
||||
|
||||
local img = love.graphics.newImage(result)
|
||||
img:setFilter('linear', 'linear')
|
||||
local x, y, w, h = self:getAbsolutes()
|
||||
self.imageColor = color.white
|
||||
self.imageVisibility = 1
|
||||
self.image = img
|
||||
self.image:setWrap("repeat", "repeat")
|
||||
self.imageHeight = img:getHeight()
|
||||
self.imageWidth = img:getWidth()
|
||||
self.quad = love.graphics.newQuad(0, 0, self.imageWidth, self.imageHeight, self.imageWidth, self.imageHeight)
|
||||
|
||||
if not (band(self.type, image) == image) then
|
||||
self.type = self.type + image
|
||||
end
|
||||
end
|
||||
|
||||
function gui:newImageBase(typ, x, y, w, h, sx, sy, sw, sh)
|
||||
local c = self:newBase(image + typ, x, y, w, h, sx, sy, sw, sh)
|
||||
c.color = color.white
|
||||
c.visibility = 0
|
||||
c.scaleX = 1
|
||||
c.scaleY = 1
|
||||
local IMAGE
|
||||
|
||||
function c:getUniques()
|
||||
@ -1061,28 +1275,39 @@ function gui:newImageBase(typ, x, y, w, h, sx, sy, sw, sh)
|
||||
})
|
||||
end
|
||||
|
||||
function c:flip(vert)
|
||||
if vert then
|
||||
c.scaleY = c.scaleY * -1
|
||||
else
|
||||
c.scaleX = c.scaleX * -1
|
||||
end
|
||||
end
|
||||
|
||||
function c:getSource()
|
||||
return IMAGE
|
||||
end
|
||||
|
||||
c.setImage = function(self, i, x, y, w, h)
|
||||
if i == nil then return end
|
||||
local img = load_image(i)
|
||||
load_image(i).OnReturn(function(img)
|
||||
img = love.image.newImageData(i)
|
||||
img = love.graphics.newImage(img)
|
||||
IMAGE = i
|
||||
if type(i) == "string" then i = image_cache[i] or i end
|
||||
|
||||
if i and x then
|
||||
self.imageHeigth = h
|
||||
self.imageWidth = w
|
||||
c.imageHeight = h
|
||||
c.imageWidth = w
|
||||
|
||||
if type(i) == "string" then
|
||||
image_cache[i] = img
|
||||
i = image_cache[i]
|
||||
end
|
||||
|
||||
self.image = i
|
||||
self.image:setWrap("repeat", "repeat")
|
||||
self.imageColor = color.white
|
||||
self.quad = love.graphics.newQuad(x, y, w, h, self.image:getWidth(), self.image:getHeight())
|
||||
self.imageVisibility = 1
|
||||
c.image = i
|
||||
c.image:setWrap("repeat", "repeat")
|
||||
c.imageColor = color.white
|
||||
c.quad = love.graphics.newQuad(x, y, w, h, c.image:getWidth(), c.image:getHeight())
|
||||
c.imageVisibility = 1
|
||||
|
||||
return
|
||||
end
|
||||
@ -1091,15 +1316,14 @@ function gui:newImageBase(typ, x, y, w, h, sx, sy, sw, sh)
|
||||
img = i
|
||||
end
|
||||
|
||||
local x, y, w, h = self:getAbsolutes()
|
||||
self.imageColor = color.white
|
||||
self.imageVisibility = 1
|
||||
self.image = img
|
||||
self.image:setWrap("repeat", "repeat")
|
||||
self.imageHeigth = img:getHeight()
|
||||
self.imageWidth = img:getWidth()
|
||||
self.quad = love.graphics.newQuad(0, 0, self.imageWidth, self.imageHeigth, self.imageWidth, self.imageHeigth)
|
||||
end)
|
||||
local x, y, w, h = c:getAbsolutes()
|
||||
c.imageColor = color.white
|
||||
c.imageVisibility = 1
|
||||
c.image = img
|
||||
c.image:setWrap("repeat", "repeat")
|
||||
c.imageHeight = img:getHeight()
|
||||
c.imageWidth = img:getWidth()
|
||||
c.quad = love.graphics.newQuad(0, 0, c.imageWidth, c.imageHeight, c.imageWidth, c.imageHeight)
|
||||
end
|
||||
return c
|
||||
end
|
||||
@ -1200,9 +1424,24 @@ local drawtypes = {
|
||||
[0] = function(child, x, y, w, h) end,
|
||||
[1] = function(child, x, y, w, h)
|
||||
if child.image then
|
||||
if child.scaleX < 0 or child.scaleY < 0 then
|
||||
local sx, sy = child.scaleX, child.scaleY
|
||||
local adjustX, adjustY = child.scaleX * w, child.scaleY * h
|
||||
love.graphics.setColor(child.imageColor[1], child.imageColor[2],
|
||||
child.imageColor[3], child.imageVisibility)
|
||||
love.graphics.draw(child.image, child.quad, x, y, rad(child.rotation), w / child.imageWidth, h / child.imageHeigth)
|
||||
if sx < 0 and sy < 0 then
|
||||
love.graphics.draw(child.image, child.quad, x - adjustX, y - adjustY, rad(child.rotation), (w / child.imageWidth) * child.scaleX, (h / child.imageHeight) * child.scaleY)
|
||||
elseif sx < 0 then
|
||||
love.graphics.draw(child.image, child.quad, x - adjustX, y, rad(child.rotation), (w / child.imageWidth) * child.scaleX, h / child.imageHeight)
|
||||
else
|
||||
love.graphics.draw(child.image, child.quad, x, y - adjustY, rad(child.rotation), w / child.imageWidth, (h / child.imageHeight) * child.scaleY)
|
||||
end
|
||||
else
|
||||
love.graphics.setColor(child.imageColor[1], child.imageColor[2],
|
||||
child.imageColor[3], child.imageVisibility)
|
||||
|
||||
love.graphics.draw(child.image, child.quad, x, y, rad(child.rotation), w / child.imageWidth, h / child.imageHeight)
|
||||
end
|
||||
end
|
||||
end,
|
||||
[2] = function(child, x, y, w, h)
|
||||
@ -1251,7 +1490,7 @@ local drawtypes = {
|
||||
if child.video and child.playing then
|
||||
love.graphics.setColor(child.videoColor[1], child.videoColor[2],
|
||||
child.videoColor[3], child.videoVisibility)
|
||||
if w ~= child.imageWidth and h ~= child.imageHeigth then
|
||||
if w ~= child.imageWidth and h ~= child.imageHeight then
|
||||
love.graphics.draw(child.video, x, y, rad(child.rotation),
|
||||
w / child.videoWidth, h / child.videoHeigth)
|
||||
else
|
||||
@ -1266,7 +1505,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
|
||||
@ -1280,6 +1519,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
|
||||
@ -1292,29 +1533,37 @@ local draw_handler = function(child)
|
||||
end
|
||||
end
|
||||
|
||||
if child.shader and band(ctype, image) == 2 then
|
||||
love.graphics.setShader(child.shader)
|
||||
end
|
||||
|
||||
if child.__variables.clip[1] then
|
||||
local clip = child.__variables.clip
|
||||
love.graphics.setScissor(clip[2], clip[3], clip[4], clip[5])
|
||||
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)
|
||||
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)
|
||||
@ -1334,18 +1583,27 @@ local draw_handler = function(child)
|
||||
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
|
||||
drawtypes[band(ctype, video)](child, x, y, w, h)
|
||||
drawtypes[band(ctype, image)](child, x, y, w, h)
|
||||
drawtypes[band(ctype, text)](child, x, y, w, h)
|
||||
drawtypes[band(ctype, box)](child, x, y, w, h)
|
||||
|
||||
if child.post then child:post() end
|
||||
|
||||
if child.__variables.clip[1] then
|
||||
love.graphics.setScissor() -- Remove the scissor
|
||||
end
|
||||
|
||||
if child.shader then
|
||||
love.graphics.setShader()
|
||||
end
|
||||
end
|
||||
|
||||
gui.draw_handler = draw_handler
|
||||
|
||||
drawer:newLoop(function()
|
||||
local children = gui:getAllChildren()
|
||||
for i = 1, #children do
|
||||
@ -1359,9 +1617,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
|
||||
@ -1376,8 +1664,10 @@ gui.virtual.dualDim.offset.size.x = w
|
||||
gui.virtual.dualDim.offset.size.y = h
|
||||
gui.virtual.w = w
|
||||
gui.virtual.h = h
|
||||
gui.virtual.parent = gui.virtual
|
||||
|
||||
-- Root gui
|
||||
gui.parent = gui
|
||||
gui.type = frame
|
||||
gui.children = {}
|
||||
gui.dualDim = gui:newDualDim()
|
||||
@ -1390,48 +1680,58 @@ gui.dualDim.offset.size.y = h
|
||||
gui.w = w
|
||||
gui.h = h
|
||||
|
||||
local g_width, g_height
|
||||
local function GetSizeAdjustedToAspectRatio(dWidth, dHeight)
|
||||
local isLandscape = g_width > g_height
|
||||
function gui:GetSizeAdjustedToAspectRatio(dWidth, dHeight)
|
||||
|
||||
local newHeight = 0
|
||||
local newWidth = 0
|
||||
|
||||
if g_width / g_height > dWidth / dHeight then
|
||||
newHeight = dWidth * g_height / g_width
|
||||
if self.g_width / self.g_height > dWidth / dHeight then
|
||||
newHeight = dWidth * self.g_height / self.g_width
|
||||
newWidth = dWidth
|
||||
else
|
||||
newWidth = dHeight * g_width / g_height
|
||||
newWidth = dHeight * self.g_width / self.g_height
|
||||
newHeight = dHeight
|
||||
end
|
||||
|
||||
return newWidth, newHeight, (dWidth-newWidth)/2, (dHeight-newHeight)/2
|
||||
end
|
||||
|
||||
--gui.GetSizeAdjustedToAspectRatio = GetSizeAdjustedToAspectRatio
|
||||
|
||||
function gui:setAspectSize(w, h)
|
||||
if w and h then
|
||||
g_width, g_height = w, h
|
||||
gui.aspect_ratio = true
|
||||
self.g_width, self.g_height = w, h
|
||||
else
|
||||
gui.aspect_ratio = false
|
||||
self.g_width, self.g_height = 0, 0
|
||||
end
|
||||
end
|
||||
|
||||
gui.Events.OnResized(function(w, h)
|
||||
if gui.aspect_ratio then
|
||||
local nw, nh, xt, yt = GetSizeAdjustedToAspectRatio(w, h)
|
||||
print(nw, nh, xt, yt)
|
||||
local nw, nh, xt, yt = gui:GetSizeAdjustedToAspectRatio(w, h)
|
||||
gui.x = xt
|
||||
gui.y = yt
|
||||
gui.dualDim.offset.size.x = nw
|
||||
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)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user