2016-04-02 03:45:43 +00:00
unless love.getVersion
2016-04-05 03:59:42 +00:00
error "Pop.Box only supports LOVE versions >= 0.9.1"
2016-04-02 03:45:43 +00:00
2016-02-23 03:55:05 +00:00
import filesystem, graphics from love
import insert from table
2016-04-02 03:45:43 +00:00
import inheritsFromElement from require "#{...}/util"
2016-02-23 03:55:05 +00:00
path = ...
2016-02-25 01:02:56 +00:00
pop = {}
pop.elements = {}
2016-03-29 00:59:12 +00:00
pop.skins = {}
2016-04-02 03:45:43 +00:00
pop.events = {}
2016-02-25 01:02:56 +00:00
2016-04-17 06:43:15 +00:00
pop.screen = false -- initialized in pop.load()
2016-03-30 17:50:33 +00:00
pop.focused = false
2016-03-29 00:59:12 +00:00
-- loads elements and skins, creates pop.screen (intended to only be called once at the beginning)
2016-02-25 01:02:56 +00:00
pop.load = ->
elements = filesystem.getDirectoryItems "#{path}/elements"
2016-03-30 21:01:15 +00:00
2016-02-25 01:02:56 +00:00
for i = 1, #elements
2016-03-29 00:59:12 +00:00
-- only attempt to load lua files
unless elements[i]\sub(-4) == ".lua"
continue
-- load into pop.elements table
2016-02-25 01:02:56 +00:00
name = elements[i]\sub 1, -5
pop.elements[name] = require "#{path}/elements/#{name}"
2016-04-03 07:27:15 +00:00
if pop.elements[name].load
pop.elements[name].load pop
2016-03-29 00:59:12 +00:00
print "element loaded: \"#{name}\""
-- create pop.element() wrapper if possible
unless pop[name]
if pop.elements[name].wrap
pop[name] = pop.elements[name].wrap pop
else
pop[name] = (...) ->
return pop.create(name, ...)
2016-02-25 01:02:56 +00:00
2016-03-29 00:59:12 +00:00
print "wrapper created: \"pop.#{name}()\""
2016-02-25 01:02:56 +00:00
2016-03-29 00:59:12 +00:00
-- works just like above, except no wrappers
skins = filesystem.getDirectoryItems "#{path}/skins"
2016-03-30 21:01:15 +00:00
2016-03-29 00:59:12 +00:00
for i = 1, #skins
unless skins[i]\sub(-4) == ".lua"
continue
2016-03-30 21:01:15 +00:00
2016-03-29 00:59:12 +00:00
name = skins[i]\sub 1, -5
pop.skins[name] = require "#{path}/skins/#{name}"
2016-03-30 21:01:15 +00:00
2016-03-29 00:59:12 +00:00
print "skin loaded: \"#{name}\""
2016-02-25 01:02:56 +00:00
2016-04-01 21:14:24 +00:00
-- load extensions by just running them via require
extensions = filesystem.getDirectoryItems "#{path}/extensions"
for i = 1, #extensions
unless extensions[i]\sub(-4) == ".lua"
continue
name = extensions[i]\sub 1, -5
require "#{path}/extensions/#{name}"
2016-04-02 03:45:43 +00:00
print "extension loaded: \"#{name}\""
2016-04-17 06:43:15 +00:00
-- main window (called screen because there is a window element class)
2016-03-29 00:59:12 +00:00
pop.screen = pop.create("element", false)\setSize(graphics.getWidth!, graphics.getHeight!)
print "created \"pop.screen\""
2016-02-25 01:02:56 +00:00
2016-04-01 21:10:40 +00:00
-- creates an element with specified parent (parent can be false or non-existent)
2016-03-29 00:59:12 +00:00
pop.create = (element, parent=pop.screen, ...) ->
2016-04-17 06:43:15 +00:00
-- if valid parent element (includes default of pop.screen when no parent has been passed)
2016-04-02 03:45:43 +00:00
if inheritsFromElement parent
2016-04-03 06:33:18 +00:00
element = pop.elements[element](parent, ...)
2016-04-01 22:48:58 +00:00
insert parent.child, element
2016-04-17 06:43:15 +00:00
-- if explicitly no parent
2016-04-02 03:45:43 +00:00
elseif parent == false
2016-04-03 06:33:18 +00:00
element = pop.elements[element](false, ...)
2016-04-17 06:43:15 +00:00
-- else we use pop.screen, and "parent" is actually first argument
2016-04-01 01:59:16 +00:00
else
2016-04-03 06:33:18 +00:00
element = pop.elements[element](pop.screen, parent, ...)
2016-04-01 22:48:58 +00:00
insert pop.screen.child, element
2016-03-29 00:59:12 +00:00
return element
pop.update = (dt, element=pop.screen) ->
unless element.excludeUpdate
2016-02-25 01:02:56 +00:00
if element.update
element\update dt
for i = 1, #element.child
pop.update dt, element.child[i]
2016-02-23 03:55:05 +00:00
2016-03-29 00:59:12 +00:00
pop.draw = (element=pop.screen) ->
unless element.excludeDraw
2016-02-25 01:02:56 +00:00
if element.draw
2016-03-29 00:59:12 +00:00
element\draw!
2016-02-25 01:02:56 +00:00
for i = 1, #element.child
2016-03-29 00:59:12 +00:00
pop.draw element.child[i]
2016-02-25 01:02:56 +00:00
2016-04-02 03:45:43 +00:00
pop.mousemoved = (x, y, dx, dy) =>
if pop.focused and pop.focused.mousemoved
return pop.focused\mousemoved x, y, dx, dy
return false
pop.mousepressed = (x, y, button, element) ->
unless element
print "mousepressed", x, y, button
element = pop.screen
2016-03-30 21:38:46 +00:00
2016-03-30 17:50:33 +00:00
handled = false
2016-04-02 03:45:43 +00:00
2016-03-30 17:50:33 +00:00
if (x >= element.x) and (x <= element.x + element.w) and (y >= element.y) and (y <= element.y + element.h)
2016-04-17 06:58:17 +00:00
if element.mousepressed and (not element.excludeDraw)
2016-03-30 17:50:33 +00:00
handled = element\mousepressed x - element.x, y - element.y, button
if handled
pop.focused = element
2016-04-03 06:33:18 +00:00
pop.events[button] = element
2016-03-30 17:50:33 +00:00
else
for i = 1, #element.child
handled = pop.mousepressed x, y, button, element.child[i]
if handled
break
2016-02-25 01:02:56 +00:00
2016-04-02 03:45:43 +00:00
return handled
2016-03-30 21:38:46 +00:00
2016-04-02 03:45:43 +00:00
pop.mousereleased = (x, y, button) ->
print "mousereleased", x, y, button
2016-03-30 21:38:46 +00:00
2016-04-02 03:45:43 +00:00
clickedHandled = false
mousereleasedHandled = false
2016-03-30 21:38:46 +00:00
2016-04-02 03:45:43 +00:00
if element = pop.events[button]
2016-04-17 07:29:27 +00:00
if element.clicked and (not element.excludeDraw) --and (x >= element.x) and (x <= element.x + element.w) and (y >= element.y) and (y <= element.y + element.h)
2016-04-02 03:45:43 +00:00
if clickedHandled = element\clicked x - element.x, y - element.y, button
pop.events[button] = nil
2016-03-30 21:38:46 +00:00
2016-04-17 07:29:27 +00:00
if element.mousereleased
2016-04-02 03:45:43 +00:00
if mousereleasedHandled = element\mousereleased x - element.x, y - element.y, button
pop.events[button] = nil
2016-03-30 21:38:46 +00:00
2016-04-02 03:45:43 +00:00
return clickedHandled, mousereleasedHandled
2016-02-25 01:02:56 +00:00
pop.keypressed = (key) ->
2016-03-29 00:59:12 +00:00
print "keypressed", key
2016-04-17 07:29:27 +00:00
element = pop.focused
if element and element.keypressed and (not element.excludeDraw)
return element.keypressed key
return false
2016-02-25 01:02:56 +00:00
pop.keyreleased = (key) ->
2016-03-29 00:59:12 +00:00
print "keyreleased", key
2016-04-17 07:29:27 +00:00
element = pop.focused
if element and element.keyreleased
return element.keyreleased key
return false
2016-02-25 01:02:56 +00:00
pop.textinput = (text) ->
2016-03-29 00:59:12 +00:00
print "textinput", text
2016-04-17 07:29:27 +00:00
element = pop.focused
if element and element.textinput and (not element.excludeDraw)
return element.textinput text
return false
2016-03-29 00:59:12 +00:00
2016-04-04 08:16:32 +00:00
--TODO rewrite skin system to not rely on knowing internals of elements,
-- instead call functions like setColor and setBackground
2016-03-29 00:59:12 +00:00
-- skins an element (and its children unless depth == true or 0)
-- depth can be an integer for how many levels to go down when skinning
-- defaults to pop.screen and the default skin
pop.skin = (element=pop.screen, skin=pop.skins.default, depth) ->
if element.background and skin.background
2016-02-25 01:02:56 +00:00
element.background = skin.background
2016-03-29 00:59:12 +00:00
if element.color and skin.color
2016-02-25 01:02:56 +00:00
element.color = skin.color
2016-03-29 00:59:12 +00:00
if element.font and skin.font
2016-02-25 01:02:56 +00:00
element.font = skin.font
2016-02-23 03:55:05 +00:00
2016-03-29 00:59:12 +00:00
unless depth or (depth == 0)
if depth == tonumber depth
for i = 1, #element.child
pop.skin element.child[i], skin, depth - 1
else
for i = 1, #element.child
pop.skin element.child[i], skin, false
2016-02-25 01:02:56 +00:00
2016-03-29 00:59:12 +00:00
pop.debugDraw = (element=pop.screen) ->
2016-02-25 01:02:56 +00:00
if element.debugDraw
element\debugDraw!
else
graphics.setLineWidth 1
2016-03-29 00:59:12 +00:00
graphics.setLineColor 0, 0, 0, 100
2016-02-25 01:02:56 +00:00
graphics.rectangle "fill", element.x, element.y, element.w, element.h
graphics.setColor 150, 150, 150, 150
graphics.rectangle "line", element.x, element.y, element.w, element.h
graphics.setColor 200, 200, 200, 255
graphics.print ".", element.x, element.y
for i = 1, #element.child
pop.debugDraw element.child[i]
pop.load!
return pop