LoveFrames/libraries/util.lua
Kenny Shields 271b9966c1 Fix #110
2014-02-24 17:26:18 -05:00

369 lines
10 KiB
Lua

--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
-- util library
loveframes.util = {}
--[[---------------------------------------------------------
- func: SetActiveSkin(name)
- desc: sets the active skin
--]]---------------------------------------------------------
function loveframes.util.SetActiveSkin(name)
loveframes.config["ACTIVESKIN"] = name
end
--[[---------------------------------------------------------
- func: GetActiveSkin()
- desc: gets the active skin
--]]---------------------------------------------------------
function loveframes.util.GetActiveSkin()
local index = loveframes.config["ACTIVESKIN"]
local skin = loveframes.skins.available[index]
return skin
end
--[[---------------------------------------------------------
- func: BoundingBox(x1, x2, y1, y2, w1, w2, h1, h2)
- desc: checks for a collision between two boxes
- note: I take no credit for this function
--]]---------------------------------------------------------
function loveframes.util.BoundingBox(x1, x2, y1, y2, w1, w2, h1, h2)
if x1 > x2 + w2 - 1 or y1 > y2 + h2 - 1 or x2 > x1 + w1 - 1 or y2 > y1 + h1 - 1 then
return false
else
return true
end
end
--[[---------------------------------------------------------
- func: loveframes.util.GetCollisions(object, table)
- desc: gets all objects colliding with the mouse
--]]---------------------------------------------------------
function loveframes.util.GetCollisions(object, t)
local x, y = love.mouse.getPosition()
local curstate = loveframes.state
local object = object or loveframes.base
local visible = object.visible
local children = object.children
local internals = object.internals
local objectstate = object.state
local t = t or {}
if objectstate == curstate and visible then
local objectx = object.x
local objecty = object.y
local objectwidth = object.width
local objectheight = object.height
local col = loveframes.util.BoundingBox(x, objectx, y, objecty, 1, objectwidth, 1, objectheight)
local collide = object.collide
if col and collide then
local clickbounds = object.clickbounds
if clickbounds then
local cx = clickbounds.x
local cy = clickbounds.y
local cwidth = clickbounds.width
local cheight = clickbounds.height
local clickcol = loveframes.util.BoundingBox(x, cx, y, cy, 1, cwidth, 1, cheight)
if clickcol then
table.insert(t, object)
end
else
table.insert(t, object)
end
end
if children then
for k, v in ipairs(children) do
loveframes.util.GetCollisions(v, t)
end
end
if internals then
for k, v in ipairs(internals) do
local type = v.type
if type ~= "tooltip" then
loveframes.util.GetCollisions(v, t)
end
end
end
end
return t
end
--[[---------------------------------------------------------
- func: loveframes.util.GetAllObjects(object, table)
- desc: gets all active objects
--]]---------------------------------------------------------
function loveframes.util.GetAllObjects(object, t)
local object = object or loveframes.base
local internals = object.internals
local children = object.children
local t = t or {}
table.insert(t, object)
if internals then
for k, v in ipairs(internals) do
loveframes.util.GetAllObjects(v, t)
end
end
if children then
for k, v in ipairs(children) do
loveframes.util.GetAllObjects(v, t)
end
end
return t
end
--[[---------------------------------------------------------
- func: GetDirectoryContents(directory, table)
- desc: gets the contents of a directory and all of
its subdirectories
--]]---------------------------------------------------------
function loveframes.util.GetDirectoryContents(dir, t)
local version = love._version
local dir = dir
local t = t or {}
local dirs = {}
local files
if version == "0.9.0" then
files = love.filesystem.getDirectoryItems(dir)
else
files = love.filesystem.enumerate(dir)
end
for k, v in ipairs(files) do
local isdir = love.filesystem.isDirectory(dir.. "/" ..v)
if isdir == true then
table.insert(dirs, dir.. "/" ..v)
else
local parts = loveframes.util.SplitString(v, "([.])")
local extension = parts[#parts]
parts[#parts] = nil
local name = table.concat(parts)
table.insert(t, {path = dir, fullpath = dir.. "/" ..v, requirepath = dir:gsub("/", ".") .. "." ..name, name = name, extension = extension})
end
end
if #dirs > 0 then
for k, v in ipairs(dirs) do
t = loveframes.util.GetDirectoryContents(v, t)
end
end
return t
end
--[[---------------------------------------------------------
- func: Round(num, idp)
- desc: rounds a number based on the decimal limit
- note: I take no credit for this function
--]]---------------------------------------------------------
function loveframes.util.Round(num, idp)
local mult = 10^(idp or 0)
if num >= 0 then
return math.floor(num * mult + 0.5) / mult
else
return math.ceil(num * mult - 0.5) / mult
end
end
--[[---------------------------------------------------------
- func: SplitString(string, pattern)
- desc: splits a string into a table based on a given pattern
- note: I take no credit for this function
--]]---------------------------------------------------------
function loveframes.util.SplitString(str, pat)
local t = {} -- NOTE: use {n = 0} in Lua-5.0
if pat == " " then
local fpat = "(.-)" .. pat
local last_end = 1
local s, e, cap = str:find(fpat, 1)
while s do
if s ~= #str then
cap = cap .. " "
end
if s ~= 1 or cap ~= "" then
table.insert(t,cap)
end
last_end = e+1
s, e, cap = str:find(fpat, last_end)
end
if last_end <= #str then
cap = str:sub(last_end)
table.insert(t, cap)
end
else
local fpat = "(.-)" .. pat
local last_end = 1
local s, e, cap = str:find(fpat, 1)
while s do
if s ~= 1 or cap ~= "" then
table.insert(t,cap)
end
last_end = e+1
s, e, cap = str:find(fpat, last_end)
end
if last_end <= #str then
cap = str:sub(last_end)
table.insert(t, cap)
end
end
return t
end
--[[---------------------------------------------------------
- func: RemoveAll()
- desc: removes all gui elements
--]]---------------------------------------------------------
function loveframes.util.RemoveAll()
loveframes.base.children = {}
loveframes.base.internals = {}
loveframes.hoverobject = false
loveframes.downobject = false
loveframes.modalobject = false
loveframes.inputobject = false
loveframes.hover = false
end
--[[---------------------------------------------------------
- func: loveframes.util.TableHasValue(table, value)
- desc: checks to see if a table has a specific value
--]]---------------------------------------------------------
function loveframes.util.TableHasValue(table, value)
for k, v in pairs(table) do
if v == value then
return true
end
end
return false
end
--[[---------------------------------------------------------
- func: loveframes.util.TableHasKey(table, key)
- desc: checks to see if a table has a specific key
--]]---------------------------------------------------------
function loveframes.util.TableHasKey(table, key)
return table[key] ~= nil
end
--[[---------------------------------------------------------
- func: loveframes.util.Error(message)
- desc: displays a formatted error message
--]]---------------------------------------------------------
function loveframes.util.Error(message)
error("[Love Frames] " ..message)
end
--[[---------------------------------------------------------
- func: loveframes.util.GetCollisionCount()
- desc: gets the total number of objects colliding with
the mouse
--]]---------------------------------------------------------
function loveframes.util.GetCollisionCount()
return loveframes.collisioncount
end
--[[---------------------------------------------------------
- func: loveframes.util.GetHover()
- desc: returns loveframes.hover, can be used to check
if the mouse is colliding with a visible
Love Frames object
--]]---------------------------------------------------------
function loveframes.util.GetHover()
return loveframes.hover
end
--[[---------------------------------------------------------
- func: RectangleCollisionCheck(rect1, rect2)
- desc: checks for a collision between two rectangles
based on two tables containing rectangle sizes
and positions
--]]---------------------------------------------------------
function loveframes.util.RectangleCollisionCheck(rect1, rect2)
return loveframes.util.BoundingBox(rect1.x, rect2.x, rect1.y, rect2.y, rect1.width, rect2.width, rect1.height, rect2.height)
end
--[[---------------------------------------------------------
- func: loveframes.util.DeepCopy(orig)
- desc: copies a table
- note: I take not credit for this function
--]]---------------------------------------------------------
function loveframes.util.DeepCopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in next, orig, nil do
copy[loveframes.util.DeepCopy(orig_key)] = loveframes.util.DeepCopy(orig_value)
end
setmetatable(copy, loveframes.util.DeepCopy(getmetatable(orig)))
else -- number, string, boolean, etc
copy = orig
end
return copy
end
--[[---------------------------------------------------------
- func: loveframes.util.GetHoverObject()
- desc: returns loveframes.hoverobject
--]]---------------------------------------------------------
function loveframes.util.GetHoverObject()
return loveframes.hoverobject
end
--[[---------------------------------------------------------
- func: loveframes.util.IsCtrlDown()
- desc: checks for ctrl, for use with multiselect, copy,
paste, and such. On OS X it actually looks for cmd.
--]]---------------------------------------------------------
function loveframes.util.IsCtrlDown()
if love._os == "OS X" then
return love.keyboard.isDown("lmeta") or love.keyboard.isDown("rmeta") or
love.keyboard.isDown("lgui") or love.keyboard.isDown("rgui")
end
return love.keyboard.isDown("lctrl") or love.keyboard.isDown("rctrl")
end