mirror of
https://github.com/linux-man/LoveFrames.git
synced 2024-11-26 05:14:21 +00:00
510 lines
12 KiB
Lua
510 lines
12 KiB
Lua
--[[------------------------------------------------
|
|
-- Love Frames - A GUI library for LOVE --
|
|
-- Copyright (c) 2012 Kenny Shields --
|
|
--]]------------------------------------------------
|
|
|
|
-- frame class
|
|
local newobject = loveframes.NewObject("frame", "loveframes_object_frame", true)
|
|
|
|
--[[---------------------------------------------------------
|
|
- func: initialize()
|
|
- desc: initializes the object
|
|
--]]---------------------------------------------------------
|
|
function newobject:initialize()
|
|
|
|
self.type = "frame"
|
|
self.name = "Frame"
|
|
self.width = 300
|
|
self.height = 150
|
|
self.clickx = 0
|
|
self.clicky = 0
|
|
self.internal = false
|
|
self.draggable = true
|
|
self.screenlocked = false
|
|
self.parentlocked = false
|
|
self.dragging = false
|
|
self.modal = false
|
|
self.modalbackground = false
|
|
self.showclose = true
|
|
self.internals = {}
|
|
self.children = {}
|
|
self.OnClose = nil
|
|
|
|
-- create the close button for the frame
|
|
local close = loveframes.objects["closebutton"]:new()
|
|
close.parent = self
|
|
close.OnClick = function()
|
|
local onclose = self.OnClose
|
|
self:Remove()
|
|
if onclose then
|
|
onclose(self)
|
|
end
|
|
end
|
|
|
|
table.insert(self.internals, close)
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
- func: update(deltatime)
|
|
- desc: updates the element
|
|
--]]---------------------------------------------------------
|
|
function newobject:update(dt)
|
|
|
|
local visible = self.visible
|
|
local alwaysupdate = self.alwaysupdate
|
|
|
|
if not visible then
|
|
if not alwaysupdate then
|
|
return
|
|
end
|
|
end
|
|
|
|
local x, y = love.mouse.getPosition()
|
|
local showclose = self.showclose
|
|
local close = self.internals[1]
|
|
local dragging = self.dragging
|
|
local screenlocked = self.screenlocked
|
|
local parentlocked = self.parentlocked
|
|
local modal = self.modal
|
|
local base = loveframes.base
|
|
local basechildren = base.children
|
|
local numbasechildren = #basechildren
|
|
local draworder = self.draworder
|
|
local children = self.children
|
|
local internals = self.internals
|
|
local parent = self.parent
|
|
local update = self.Update
|
|
|
|
self:CheckHover()
|
|
|
|
-- dragging check
|
|
if dragging then
|
|
if parent == base then
|
|
self.x = x - self.clickx
|
|
self.y = y - self.clicky
|
|
else
|
|
self.staticx = x - self.clickx
|
|
self.staticy = y - self.clicky
|
|
end
|
|
end
|
|
|
|
-- if screenlocked then keep within screen
|
|
if screenlocked then
|
|
local width = love.graphics.getWidth()
|
|
local height = love.graphics.getHeight()
|
|
local selfwidth = self.width
|
|
local selfheight = self.height
|
|
if self.x < 0 then
|
|
self.x = 0
|
|
end
|
|
if self.x + selfwidth > width then
|
|
self.x = width - selfwidth
|
|
end
|
|
if self.y < 0 then
|
|
self.y = 0
|
|
end
|
|
if self.y + selfheight > height then
|
|
self.y = height - selfheight
|
|
end
|
|
end
|
|
|
|
if parentlocked then
|
|
local width = self.parent.width
|
|
local height = self.parent.height
|
|
local selfwidth = self.width
|
|
local selfheight = self.height
|
|
if self.staticx < 0 then
|
|
self.staticx = 0
|
|
end
|
|
if self.staticx + selfwidth > width then
|
|
self.staticx = width - selfwidth
|
|
end
|
|
if self.staticy < 0 then
|
|
self.staticy = 0
|
|
end
|
|
if self.staticy + selfheight > height then
|
|
self.staticy = height - selfheight
|
|
end
|
|
end
|
|
|
|
if modal then
|
|
local tip = false
|
|
local key = 0
|
|
for k, v in ipairs(basechildren) do
|
|
if v.type == "tooltip" and v.show == true then
|
|
tip = v
|
|
key = k
|
|
end
|
|
end
|
|
if tip ~= false then
|
|
self:Remove()
|
|
self.modalbackground:Remove()
|
|
table.insert(basechildren, key - 2, self.modalbackground)
|
|
table.insert(basechildren, key - 1, self)
|
|
end
|
|
if self.modalbackground.draworder > self.draworder then
|
|
self:MakeTop()
|
|
end
|
|
end
|
|
|
|
if parent ~= base then
|
|
self.x = self.parent.x + self.staticx
|
|
self.y = self.parent.y + self.staticy
|
|
end
|
|
|
|
for k, v in ipairs(internals) do
|
|
v:update(dt)
|
|
end
|
|
|
|
for k, v in ipairs(children) do
|
|
v:update(dt)
|
|
end
|
|
|
|
if update then
|
|
update(self, dt)
|
|
end
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
- func: draw()
|
|
- desc: draws the object
|
|
--]]---------------------------------------------------------
|
|
function newobject:draw()
|
|
|
|
local visible = self.visible
|
|
|
|
if not visible then
|
|
return
|
|
end
|
|
|
|
local children = self.children
|
|
local internals = self.internals
|
|
local skins = loveframes.skins.available
|
|
local skinindex = loveframes.config["ACTIVESKIN"]
|
|
local defaultskin = loveframes.config["DEFAULTSKIN"]
|
|
local selfskin = self.skin
|
|
local skin = skins[selfskin] or skins[skinindex]
|
|
local drawfunc = skin.DrawFrame or skins[defaultskin].DrawFrame
|
|
local draw = self.Draw
|
|
local drawcount = loveframes.drawcount
|
|
|
|
-- set the object's draw order
|
|
self:SetDrawOrder()
|
|
|
|
if draw then
|
|
draw(self)
|
|
else
|
|
drawfunc(self)
|
|
end
|
|
|
|
for k, v in ipairs(internals) do
|
|
v:draw()
|
|
end
|
|
|
|
-- loop through the object's children and draw them
|
|
for k, v in ipairs(children) do
|
|
v:draw()
|
|
end
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
- func: mousepressed(x, y, button)
|
|
- desc: called when the player presses a mouse button
|
|
--]]---------------------------------------------------------
|
|
function newobject:mousepressed(x, y, button)
|
|
|
|
local visible = self.visible
|
|
|
|
if not visible then
|
|
return
|
|
end
|
|
|
|
local width = self.width
|
|
local height = self.height
|
|
local selfcol = loveframes.util.BoundingBox(x, self.x, y, self.y, 1, self.width, 1, self.height)
|
|
local internals = self.internals
|
|
local children = self.children
|
|
local dragging = self.dragging
|
|
local parent = self.parent
|
|
local base = loveframes.base
|
|
|
|
if selfcol then
|
|
local top = self:IsTopCollision()
|
|
-- initiate dragging if not currently dragging
|
|
if not dragging and top and button == "l" then
|
|
if y < self.y + 25 and self.draggable then
|
|
if parent == base then
|
|
self.clickx = x - self.x
|
|
self.clicky = y - self.y
|
|
else
|
|
self.clickx = x - self.staticx
|
|
self.clicky = y - self.staticy
|
|
end
|
|
self.dragging = true
|
|
end
|
|
end
|
|
if top and button == "l" then
|
|
self:MakeTop()
|
|
end
|
|
end
|
|
|
|
for k, v in ipairs(internals) do
|
|
v:mousepressed(x, y, button)
|
|
end
|
|
|
|
for k, v in ipairs(children) do
|
|
v:mousepressed(x, y, button)
|
|
end
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
- func: mousereleased(x, y, button)
|
|
- desc: called when the player releases a mouse button
|
|
--]]---------------------------------------------------------
|
|
function newobject:mousereleased(x, y, button)
|
|
|
|
local visible = self.visible
|
|
|
|
if not visible then
|
|
return
|
|
end
|
|
|
|
local dragging = self.dragging
|
|
local children = self.children
|
|
local internals = self.internals
|
|
|
|
-- exit the dragging state
|
|
if dragging then
|
|
self.dragging = false
|
|
end
|
|
|
|
for k, v in ipairs(internals) do
|
|
v:mousereleased(x, y, button)
|
|
end
|
|
|
|
for k, v in ipairs(children) do
|
|
v:mousereleased(x, y, button)
|
|
end
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
- func: SetName(name)
|
|
- desc: sets the frame's name
|
|
--]]---------------------------------------------------------
|
|
function newobject:SetName(name)
|
|
|
|
self.name = name
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
- func: GetName()
|
|
- desc: gets the frame's name
|
|
--]]---------------------------------------------------------
|
|
function newobject:GetName()
|
|
|
|
return self.name
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
- func: SetDraggable(true/false)
|
|
- desc: sets whether the frame can be dragged or not
|
|
--]]---------------------------------------------------------
|
|
function newobject:SetDraggable(bool)
|
|
|
|
self.draggable = bool
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
- func: GetDraggable()
|
|
- desc: gets whether the frame can be dragged ot not
|
|
--]]---------------------------------------------------------
|
|
function newobject:GetDraggable()
|
|
|
|
return self.draggable
|
|
|
|
end
|
|
|
|
|
|
--[[---------------------------------------------------------
|
|
- func: SetScreenLocked(bool)
|
|
- desc: sets whether the frame can be moved passed the
|
|
boundaries of the window or not
|
|
--]]---------------------------------------------------------
|
|
function newobject:SetScreenLocked(bool)
|
|
|
|
self.screenlocked = bool
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
- func: GetScreenLocked()
|
|
- desc: gets whether the frame can be moved passed the
|
|
boundaries of window or not
|
|
--]]---------------------------------------------------------
|
|
function newobject:GetScreenLocked()
|
|
|
|
return self.screenlocked
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
- func: ShowCloseButton(bool)
|
|
- desc: sets whether the close button should be drawn
|
|
--]]---------------------------------------------------------
|
|
function newobject:ShowCloseButton(bool)
|
|
|
|
local close = self.internals[1]
|
|
|
|
close.visible = bool
|
|
self.showclose = bool
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
- func: MakeTop()
|
|
- desc: makes the object the top object in the drawing
|
|
order
|
|
--]]---------------------------------------------------------
|
|
function newobject:MakeTop()
|
|
|
|
local x, y = love.mouse.getPosition()
|
|
local key = 0
|
|
local base = loveframes.base
|
|
local basechildren = base.children
|
|
local numbasechildren = #basechildren
|
|
local parent = self.parent
|
|
|
|
-- check to see if the object's parent is not the base object
|
|
if parent ~= base then
|
|
local baseparent = self:GetBaseParent()
|
|
if baseparent.type == "frame" then
|
|
baseparent:MakeTop()
|
|
end
|
|
return
|
|
end
|
|
|
|
-- check to see if the object is the only child of the base object
|
|
if numbasechildren == 1 then
|
|
return
|
|
end
|
|
|
|
-- check to see if the object is already at the top
|
|
if basechildren[numbasechildren] == self then
|
|
return
|
|
end
|
|
|
|
-- make this the top object
|
|
for k, v in ipairs(basechildren) do
|
|
if v == self then
|
|
table.remove(basechildren, k)
|
|
table.insert(basechildren, self)
|
|
key = k
|
|
break
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
- func: SetModal(bool)
|
|
- desc: makes the object the top object in the drawing
|
|
order
|
|
--]]---------------------------------------------------------
|
|
function newobject:SetModal(bool)
|
|
|
|
local modalobject = loveframes.modalobject
|
|
local mbackground = self.modalbackground
|
|
local parent = self.parent
|
|
local base = loveframes.base
|
|
|
|
if parent ~= base then
|
|
return
|
|
end
|
|
|
|
self.modal = bool
|
|
|
|
if bool then
|
|
if modalobject then
|
|
modalobject:SetModal(false)
|
|
end
|
|
loveframes.modalobject = self
|
|
|
|
if not mbackground then
|
|
self.modalbackground = loveframes.objects["modalbackground"]:new(self)
|
|
self.modal = true
|
|
end
|
|
else
|
|
if modalobject == self then
|
|
loveframes.modalobject = false
|
|
if mbackground then
|
|
self.modalbackground:Remove()
|
|
self.modalbackground = false
|
|
self.modal = false
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
- func: GetModal()
|
|
- desc: gets whether or not the object is in a modal
|
|
state
|
|
--]]---------------------------------------------------------
|
|
function newobject:GetModal()
|
|
|
|
return self.modal
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
- func: SetVisible(bool)
|
|
- desc: set's whether the object is visible or not
|
|
--]]---------------------------------------------------------
|
|
function newobject:SetVisible(bool)
|
|
|
|
local children = self.children
|
|
local internals = self.internals
|
|
local closebutton = internals[1]
|
|
|
|
self.visible = bool
|
|
|
|
for k, v in ipairs(children) do
|
|
v:SetVisible(bool)
|
|
end
|
|
|
|
if self.showclose then
|
|
closebutton.visible = bool
|
|
end
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
- func: SetParentLocked(bool)
|
|
- desc: sets whether the frame can be moved passed the
|
|
boundaries of it's parent or not
|
|
--]]---------------------------------------------------------
|
|
function newobject:SetParentLocked(bool)
|
|
|
|
self.parentlocked = bool
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
- func: GetParentLocked(bool)
|
|
- desc: gets whether the frame can be moved passed the
|
|
boundaries of it's parent or not
|
|
--]]---------------------------------------------------------
|
|
function newobject:GetParentLocked()
|
|
|
|
return self.parentlocked
|
|
|
|
end |