Can now drag items, clipDescendants now work
This commit is contained in:
parent
435c632b47
commit
e84ae751b2
211
gui/init.lua
211
gui/init.lua
@ -6,13 +6,81 @@ local updater = multi:newProcessor("UpdateManager",true)
|
|||||||
local drawer = multi:newProcessor("DrawManager",true)
|
local drawer = multi:newProcessor("DrawManager",true)
|
||||||
local bit = require("bit")
|
local bit = require("bit")
|
||||||
local band, bor = bit.band, bit.bor
|
local band, bor = bit.band, bit.bor
|
||||||
local floor, ceil = math.floor,math.ceil
|
local clips = {}
|
||||||
|
local max, min, abs, rad, floor, ceil = math.max, math.min, math.abs, math.rad, math.floor,math.ceil
|
||||||
gui.__index = gui
|
gui.__index = gui
|
||||||
gui.MOUSE_PRIMARY = 1
|
gui.MOUSE_PRIMARY = 1
|
||||||
gui.MOUSE_SECONDARY = 2
|
gui.MOUSE_SECONDARY = 2
|
||||||
gui.MOUSE_MIDDLE = 3
|
gui.MOUSE_MIDDLE = 3
|
||||||
|
|
||||||
local frame, image, text, button, box, video = 0, 1, 2, 4, 8, 16
|
local frame, image, text, box, video = 0, 1, 2, 4, 8
|
||||||
|
|
||||||
|
-- Utils
|
||||||
|
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
function gui:moveInBounds(dx,dy)
|
||||||
|
local x, y, w, h = self:getAbsolutes()
|
||||||
|
local x1, y1, w1, h1 = self.parent:getAbsolutes()
|
||||||
|
if (x + dx >= x1 or dx > 0) and (x + w + dx <= x1 + w1 or dx < 0) and (y + dy >= y1 or dy > 0) and (y + h + dy <= y1 + h1 or dy < 0) then
|
||||||
|
self:move(dx,dy)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function intersecpt(x1,y1,x2,y2,x3,y3,x4,y4)
|
||||||
|
|
||||||
|
-- gives bottom-left point
|
||||||
|
-- of intersection rectangle
|
||||||
|
local x5 = max(x1, x3)
|
||||||
|
local y5 = max(y1, y3)
|
||||||
|
|
||||||
|
-- gives top-right point
|
||||||
|
-- of intersection rectangle
|
||||||
|
local x6 = min(x2, x4);
|
||||||
|
local y6 = min(y2, y4);
|
||||||
|
|
||||||
|
-- no intersection
|
||||||
|
if x5 > x6 or y5 > y6 then
|
||||||
|
return 0, 0, 0, 0 -- Return a no
|
||||||
|
end
|
||||||
|
|
||||||
|
-- gives top-left point
|
||||||
|
-- of intersection rectangle
|
||||||
|
local x7 = x5
|
||||||
|
local y7 = y6
|
||||||
|
|
||||||
|
-- gives bottom-right point
|
||||||
|
-- of intersection rectangle
|
||||||
|
local x8 = x6
|
||||||
|
local y8 = y5
|
||||||
|
|
||||||
|
return x7, y7, abs(x7-x8), abs(y7-y8)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function toCoordPoints(x, y, w, h)
|
||||||
|
return x,y,x+w,y+h
|
||||||
|
end
|
||||||
|
|
||||||
|
function gui:intersecpt(x, y, w, h)
|
||||||
|
local x1,y1,x2,y2 = toCoordPoints(self:getAbsolutes())
|
||||||
|
local x3,y3,x4,y4 = toCoordPoints(x,y,w,h)
|
||||||
|
|
||||||
|
return intersecpt(x1,y1,x2,y2,x3,y3,x4,y4)
|
||||||
|
end
|
||||||
|
|
||||||
|
function gui:isDescendantOf(obj)
|
||||||
|
local parent = self.parent
|
||||||
|
while parent~=gui do
|
||||||
|
if parent==obj then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
parent = parent.parent
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
function gui:getChildren()
|
function gui:getChildren()
|
||||||
return self.children
|
return self.children
|
||||||
@ -41,7 +109,7 @@ function gui:getAllChildren()
|
|||||||
local Objs = self:getChildren()
|
local Objs = self:getChildren()
|
||||||
for i=1,#Objs do
|
for i=1,#Objs do
|
||||||
if Objs[i].visible==true then
|
if Objs[i].visible==true then
|
||||||
table.insert(Stuff,Objs[i])
|
table.insert(Stuff, Objs[i])
|
||||||
local Items = Objs[i]:getChildren()
|
local Items = Objs[i]:getChildren()
|
||||||
if Items ~= nil then
|
if Items ~= nil then
|
||||||
Seek(Items)
|
Seek(Items)
|
||||||
@ -68,14 +136,33 @@ 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
|
||||||
|
local x, y, w, h
|
||||||
|
if self.__variables.clip[1] then
|
||||||
|
local clip = self.__variables.clip
|
||||||
|
x, y, w, h = self:intersecpt(clip[2], clip[3], clip[4], clip[5])
|
||||||
|
--x1, y1, w1, h1 = self:getAbsolutes()
|
||||||
|
return mx < x + w and mx > x and my+h < y + h and my+h > y
|
||||||
|
else
|
||||||
|
x, y, w, h = self:getAbsolutes()
|
||||||
|
end
|
||||||
|
return not(mx > x + w or mx < x or my > y + h or my < y)
|
||||||
|
end
|
||||||
|
|
||||||
-- Base Library
|
-- Base Library
|
||||||
function gui:newBase(typ,x, y, w, h, sx, sy, sw, sh)
|
function gui:newBase(typ,x, y, w, h, sx, sy, sw, sh)
|
||||||
local c = {}
|
local c = {}
|
||||||
local centerX = false
|
local centerX = false
|
||||||
local centerY = false
|
local centerY = false
|
||||||
local centering = false
|
local centering = false
|
||||||
local pressed = false
|
local dragbutton = 2
|
||||||
|
local draggable = false
|
||||||
|
|
||||||
setmetatable(c, gui)
|
setmetatable(c, gui)
|
||||||
|
c.__variables = {
|
||||||
|
clip = {false,0,0,0,0}
|
||||||
|
}
|
||||||
c.parent = self
|
c.parent = self
|
||||||
c.type = typ
|
c.type = typ
|
||||||
c.dualDim = self:newDualDim(x, y, w, h, sx, sy, sw, sh)
|
c.dualDim = self:newDualDim(x, y, w, h, sx, sy, sw, sh)
|
||||||
@ -85,41 +172,70 @@ function gui:newBase(typ,x, y, w, h, sx, sy, sw, sh)
|
|||||||
c.color = {.6,.6,.6}
|
c.color = {.6,.6,.6}
|
||||||
c.borderColor = color.black
|
c.borderColor = color.black
|
||||||
c.rotation = 0
|
c.rotation = 0
|
||||||
|
c.maxMouseButtons = 5
|
||||||
|
|
||||||
c.WhilePressing = multi:newConnection()
|
c.WhilePressing = multi:newConnection()
|
||||||
c.OnPressed = multi:newConnection()
|
c.OnPressed = multi:newConnection()
|
||||||
c.OnReleased = multi:newConnection()
|
c.OnReleased = multi:newConnection()
|
||||||
c.maxMouseButtons = 5
|
|
||||||
|
|
||||||
|
c.OnDragStart = multi:newConnection()
|
||||||
|
c.OnDragging = multi:newConnection()
|
||||||
|
c.OnDragEnd = multi:newConnection()
|
||||||
|
|
||||||
|
-- Mouse event thread
|
||||||
c:newThread(function()
|
c:newThread(function()
|
||||||
|
local dragging = false
|
||||||
|
local waiting = {}
|
||||||
|
local pressed = {}
|
||||||
|
local ox, oy = 0, 0
|
||||||
while true do
|
while true do
|
||||||
thread.sleep(.1)
|
thread.sleep(.005) -- Limits the potiential speed for events to 1/200. So 200 fps max, to be fair pressing mouse click 200 times by hand in a second is probably not possible
|
||||||
local x, y, w, h = c:getAbsolutes()
|
local x, y, w, h = c:getAbsolutes()
|
||||||
local mx, my = love.mouse.getPosition()
|
local mx, my = love.mouse.getPosition()
|
||||||
for i=1,c.maxMouseButtons do
|
for i=1,c.maxMouseButtons do
|
||||||
if love.mouse.isDown(i) and not(mx > x + w or mx < x or my > y + h or my < y) then
|
if dragging and i == dragbutton then
|
||||||
if not pressed then
|
c.OnDragging:Fire(c, mx - ox, my - oy)
|
||||||
c.OnPressed:Fire(c, i, mx, my)
|
ox = mx
|
||||||
end
|
oy = my
|
||||||
pressed = true
|
end
|
||||||
c.WhilePressing:Fire(c, i, mx, my)
|
if love.mouse.isDown(i) and c:canPress(mx,my) then
|
||||||
c:newThread(function()
|
if not pressed[i] then
|
||||||
thread.hold(function() return not(love.mouse.isDown(i)) end)
|
if draggable and love.mouse.isDown(dragbutton) then
|
||||||
if pressed then
|
if not dragging then
|
||||||
c.OnReleased:Fire(c, i, mx, my)
|
c.OnDragStart:Fire(c, mx, my)
|
||||||
|
ox, oy = mx, my
|
||||||
|
c:newThread(function()
|
||||||
|
thread.hold(function() return not(love.mouse.isDown(dragbutton)) end)
|
||||||
|
if dragging then
|
||||||
|
dragging = false
|
||||||
|
c.OnDragEnd:Fire(c,mx,my)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
dragging = true
|
||||||
end
|
end
|
||||||
pressed = false
|
c:newThread(function()
|
||||||
end)
|
c.OnPressed:Fire(c, i, mx, my)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
pressed[i] = true
|
||||||
|
-- Only process when the drag button turn is active
|
||||||
|
c.WhilePressing:Fire(c, i, mx, my)
|
||||||
|
if not waiting[i] then
|
||||||
|
waiting[i] = true
|
||||||
|
c:newThread(function()
|
||||||
|
thread.hold(function() return not(love.mouse.isDown(i)) end)
|
||||||
|
if pressed[i] then
|
||||||
|
pressed[i] = false
|
||||||
|
waiting[i] = false
|
||||||
|
c.OnReleased:Fire(c, i, mx, my)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
c:WhilePressing(function(x,y,self)
|
|
||||||
if not pressed then
|
|
||||||
pressed = true
|
|
||||||
c.OnPressed:Fire(x,y,self)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
function c:OnUpdate(func) -- Not crazy about this approach, will probably rework this
|
function c:OnUpdate(func) -- Not crazy about this approach, will probably rework this
|
||||||
if type(self)=="function" then func = self end
|
if type(self)=="function" then func = self end
|
||||||
@ -144,12 +260,23 @@ function gui:newBase(typ,x, y, w, h, sx, sy, sw, sh)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function c:enableDragging(but)
|
||||||
|
if not but then
|
||||||
|
draggable = false
|
||||||
|
return
|
||||||
|
end
|
||||||
|
dragbutton = but or dragbutton
|
||||||
|
draggable = true
|
||||||
|
end
|
||||||
|
|
||||||
function c:centerX(bool)
|
function c:centerX(bool)
|
||||||
centerX = bool
|
centerX = bool
|
||||||
if centering then return end
|
if centering then return end
|
||||||
centering = true
|
centering = true
|
||||||
centerthread()
|
centerthread()
|
||||||
end
|
end
|
||||||
|
|
||||||
function c:centerY(bool)
|
function c:centerY(bool)
|
||||||
centerY = bool
|
centerY = bool
|
||||||
if centering then return end
|
if centering then return end
|
||||||
@ -396,9 +523,9 @@ local drawtypes = {
|
|||||||
if child.image then
|
if child.image then
|
||||||
love.graphics.setColor(child.imageColor[1],child.imageColor[2],child.imageColor[3],child.imageVisibility)
|
love.graphics.setColor(child.imageColor[1],child.imageColor[2],child.imageColor[3],child.imageVisibility)
|
||||||
if w~=child.imageWidth and h~=child.imageHeigth then
|
if w~=child.imageWidth and h~=child.imageHeigth then
|
||||||
love.graphics.draw(child.image,x,y,math.rad(child.rotation),w/child.imageWidth,h/child.imageHeigth)
|
love.graphics.draw(child.image,x,y,rad(child.rotation),w/child.imageWidth,h/child.imageHeigth)
|
||||||
else
|
else
|
||||||
love.graphics.draw(child.image,child.quad,x,y,math.rad(child.rotation),w/child.imageWidth,h/child.imageHeigth)
|
love.graphics.draw(child.image,child.quad,x,y,rad(child.rotation),w/child.imageWidth,h/child.imageHeigth)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
@ -408,18 +535,15 @@ local drawtypes = {
|
|||||||
love.graphics.printf(child.text, x + child.textOffsetX, y + child.textOffsetY, w, child.align, child.rotation, child.textScaleX, child.textScaleY, 0, 0, child.textShearingFactorX, child.textShearingFactorY)
|
love.graphics.printf(child.text, x + child.textOffsetX, y + child.textOffsetY, w, child.align, child.rotation, child.textScaleX, child.textScaleY, 0, 0, child.textShearingFactorX, child.textShearingFactorY)
|
||||||
end,
|
end,
|
||||||
[4] = function(child, x, y, w, h)
|
[4] = function(child, x, y, w, h)
|
||||||
-- button
|
|
||||||
end,
|
|
||||||
[8] = function(child, x, y, w, h)
|
|
||||||
-- box
|
-- box
|
||||||
end,
|
end,
|
||||||
[16] = function(child, x, y, w, h)
|
[8] = function(child, x, y, w, h)
|
||||||
if child.video and child.playing then
|
if child.video and child.playing then
|
||||||
love.graphics.setColor(child.videoColor[1],child.videoColor[2],child.videoColor[3],child.videoVisibility)
|
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.imageHeigth then
|
||||||
love.graphics.draw(child.video,x,y,math.rad(child.rotation),w/child.videoWidth,h/child.videoHeigth)
|
love.graphics.draw(child.video,x,y,rad(child.rotation),w/child.videoWidth,h/child.videoHeigth)
|
||||||
else
|
else
|
||||||
love.graphics.draw(child.video,child.quad,x,y,math.rad(child.rotation),w/child.videoWidth,h/child.videoHeigth)
|
love.graphics.draw(child.video,child.quad,x,y,rad(child.rotation),w/child.videoWidth,h/child.videoHeigth)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
@ -438,11 +562,24 @@ drawer:newLoop(function()
|
|||||||
child.y = y
|
child.y = y
|
||||||
child.w = w
|
child.w = w
|
||||||
child.h = h
|
child.h = h
|
||||||
-- local x = (child.parent.dualDim.offset.size.x*child.dualDim.scale.pos.x)+child.dualDim.offset.pos.x+child.parent.dualDim.offset.pos.x
|
|
||||||
-- local y = (child.parent.dualDim.offset.size.y*child.dualDim.scale.pos.y)+child.dualDim.offset.pos.y+child.parent.dualDim.offset.pos.y
|
|
||||||
-- local w = (child.parent.dualDim.offset.size.x*child.dualDim.scale.size.x)+child.dualDim.offset.size.x
|
|
||||||
-- local h = (child.parent.dualDim.offset.size.y*child.dualDim.scale.size.y)+child.dualDim.offset.size.y
|
|
||||||
|
|
||||||
|
if child.clipDescendants then
|
||||||
|
local children = child:getAllChildren()
|
||||||
|
for c = 1, #children do -- Tell the children to clip themselves
|
||||||
|
local clip = children[c].__variables.clip
|
||||||
|
clip[1] = true
|
||||||
|
clip[2] = x
|
||||||
|
clip[3] = y
|
||||||
|
clip[4] = w
|
||||||
|
clip[5] = h
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if child.__variables.clip[1] then
|
||||||
|
local clip = child.__variables.clip
|
||||||
|
love.graphics.setScissor(clip[2], clip[3], clip[4], clip[5])
|
||||||
|
end
|
||||||
|
|
||||||
-- Set color
|
-- Set color
|
||||||
love.graphics.setColor(bg[1],bg[2],bg[3],vis)
|
love.graphics.setColor(bg[1],bg[2],bg[3],vis)
|
||||||
love.graphics.rectangle("fill", x, y, w, h--[[, rx, ry, segments]])
|
love.graphics.rectangle("fill", x, y, w, h--[[, rx, ry, segments]])
|
||||||
@ -452,6 +589,8 @@ drawer:newLoop(function()
|
|||||||
drawtypes[band(type,video)](child,x,y,w,h)
|
drawtypes[band(type,video)](child,x,y,w,h)
|
||||||
drawtypes[band(type,image)](child,x,y,w,h)
|
drawtypes[band(type,image)](child,x,y,w,h)
|
||||||
drawtypes[band(type,text)](child,x,y,w,h)
|
drawtypes[band(type,text)](child,x,y,w,h)
|
||||||
|
|
||||||
|
love.graphics.setScissor() -- Remove the scissor
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
40
test.lua
Normal file
40
test.lua
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
local function intersecpt(x1,y1,x2,y2,x3,y3,x4,y4)
|
||||||
|
|
||||||
|
-- gives bottom-left point
|
||||||
|
-- of intersection rectangle
|
||||||
|
local x5 = math.max(x1, x3)
|
||||||
|
local y5 = math.max(y1, y3)
|
||||||
|
|
||||||
|
-- gives top-right point
|
||||||
|
-- of intersection rectangle
|
||||||
|
local x6 = math.min(x2, x4);
|
||||||
|
local y6 = math.min(y2, y4);
|
||||||
|
|
||||||
|
-- no intersection
|
||||||
|
if x5 > x6 or y5 > y6 then
|
||||||
|
return 0,0,0,0 -- Return a no
|
||||||
|
end
|
||||||
|
|
||||||
|
-- gives top-left point
|
||||||
|
-- of intersection rectangle
|
||||||
|
local x7 = x5
|
||||||
|
local y7 = y6
|
||||||
|
|
||||||
|
-- gives bottom-right point
|
||||||
|
-- of intersection rectangle
|
||||||
|
local x8 = x6
|
||||||
|
local y8 = y5
|
||||||
|
|
||||||
|
return x7, y7, math.abs(x7-x8), math.abs(y7-y8)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function toCoordPoints(x,y,w,h)
|
||||||
|
return x,y,x+w,y+h
|
||||||
|
end
|
||||||
|
|
||||||
|
function gui:intersecpt(obj)
|
||||||
|
local x1,y1,x2,y2 = toCoordPoints(self:getAbsolutes())
|
||||||
|
local x3,y3,x4,y4 = toCoordPoints(obj:getAbsolutes())
|
||||||
|
|
||||||
|
return intersecpt(x1,y1,x2,y2,x3,y3,x4,y4)
|
||||||
|
end
|
||||||
Loading…
x
Reference in New Issue
Block a user