fix #67 using 2 spaces instead of 4

This commit is contained in:
Paul Liverman III 2017-08-28 01:49:12 -07:00
parent c33f10c18e
commit e8a76ddaf2
16 changed files with 1195 additions and 1194 deletions

View File

@ -113,35 +113,35 @@
-- @todo Document debugDraw method -- @todo Document debugDraw method
pop.keypressed = (key) -> pop.keypressed = (key) ->
print "keypressed", key print "keypressed", key
-- keypressed events must be on visible elements -- keypressed events must be on visible elements
element = pop.focused element = pop.focused
if element and element.keypressed and element.data.draw if element and element.keypressed and element.data.draw
return element.keypressed key return element.keypressed key
return false return false
pop.keyreleased = (key) -> pop.keyreleased = (key) ->
print "keyreleased", key print "keyreleased", key
-- keyreleased events are always called -- keyreleased events are always called
element = pop.focused element = pop.focused
if element and element.keyreleased if element and element.keyreleased
return element.keyreleased key return element.keyreleased key
return false return false
pop.textinput = (text) -> pop.textinput = (text) ->
print "textinput", text print "textinput", text
-- textinput events must be on visible elements -- textinput events must be on visible elements
element = pop.focused element = pop.focused
if element and element.textinput and element.data.draw if element and element.textinput and element.data.draw
return element.textinput text return element.textinput text
return false return false
pop.debugDraw = (element=pop.screen) -> pop.debugDraw = (element=pop.screen) ->
if element.debugDraw if element.debugDraw
element\debugDraw! element\debugDraw!

View File

@ -1,19 +1,19 @@
file = { file = {
"init.moon", "init.moon",
"elements/box.moon", "elements/box.moon",
"elements/button.moon", "elements/button.moon",
"elements/dynamicGrid.moon", "elements/dynamicGrid.moon",
"elements/element.moon", "elements/element.moon",
"elements/grid.moon", "elements/grid.moon",
"elements/scrollbox.moon", "elements/scrollbox.moon",
"elements/text.moon", "elements/text.moon",
"elements/window.moon", "elements/window.moon",
"extensions/streamlined_get_set.moon", "extensions/streamlined_get_set.moon",
"extensions/utility.moon", "extensions/utility.moon",
"class.moon", "class.moon",
"main.moon", "main.moon",
"util.moon", "util.moon",
"Element.luadoc", "Element.luadoc",
} }
project = "Pop.Box()" project = "Pop.Box()"

View File

@ -10,51 +10,51 @@ import graphics from love
element = require "#{(...)\sub 1, -4}/element" element = require "#{(...)\sub 1, -4}/element"
class box extends element class box extends element
--- Constructor expects nothing, or a data table describing it. --- Constructor expects nothing, or a data table describing it.
new: (@parent, @data={}, background={255, 255, 255, 255}) => new: (@parent, @data={}, background={255, 255, 255, 255}) =>
-- assume a data object with four values is actually the background -- assume a data object with four values is actually the background
if #@data == 4 if #@data == 4
background = @data background = @data
@data = nil @data = nil
super @parent, @data super @parent, @data
@data.type = "box" if @data.type == "element" @data.type = "box" if @data.type == "element"
@data.background = background unless @data.background @data.background = background unless @data.background
draw: => draw: =>
if "table" == type @data.background if "table" == type @data.background
graphics.setColor @data.background graphics.setColor @data.background
graphics.rectangle "fill", @data.x, @data.y, @data.w, @data.h graphics.rectangle "fill", @data.x, @data.y, @data.w, @data.h
else else
w, h = @data.background\getDimensions! w, h = @data.background\getDimensions!
w = @data.w / w w = @data.w / w
h = @data.h / h h = @data.h / h
graphics.setColor 255, 255, 255, 255 graphics.setColor 255, 255, 255, 255
graphics.draw @data.background, @data.x, @data.y, 0, w, h graphics.draw @data.background, @data.x, @data.y, 0, w, h
return @ return @
setBackground: (background) => setBackground: (background) =>
if background if background
@data.background = background @data.background = background
else else
error "Background must be a table representing a color, or a drawable object." error "Background must be a table representing a color, or a drawable object."
return @ return @
getBackground: => getBackground: =>
return @data.background return @data.background
setColor: (r, g, b, a=255) => setColor: (r, g, b, a=255) =>
if "table" == type r if "table" == type r
@data.background = r @data.background = r
else else
@data.background = {r, g, b, a} @data.background = {r, g, b, a}
return @ return @
getColor: => getColor: =>
if "table" == type @data.background if "table" == type @data.background
return unpack @data.background return unpack @data.background
else else
return 255, 255, 255, 255 -- if it is drawable, it is drawn with a white color return 255, 255, 255, 255 -- if it is drawable, it is drawn with a white color

View File

@ -3,7 +3,7 @@ import graphics from love
element = require "#{(...)\sub 1, -7}/element" element = require "#{(...)\sub 1, -7}/element"
class button extends element class button extends element
new: (@parent, @data={}) => new: (@parent, @data={}) =>
super @parent, @data super @parent, @data
@data.type = "button" if @data.type == "element" @data.type = "button" if @data.type == "element"

View File

@ -3,46 +3,46 @@ import graphics from love
element = require "#{(...)\sub 1, -11}/element" element = require "#{(...)\sub 1, -11}/element"
recursiveDraw = (children, x, y) -> recursiveDraw = (children, x, y) ->
for i = 1, #children for i = 1, #children
child = children[i] child = children[i]
local drawChildren local drawChildren
if child.draw if child.draw
child.data.x -= x child.data.x -= x
child.data.y -= y child.data.y -= y
drawChildren = child\draw! drawChildren = child\draw!
child.data.x += x child.data.x += x
child.data.y += y child.data.y += y
if drawChildren != false if drawChildren != false
recursiveDraw child.child, x, y recursiveDraw child.child, x, y
local canvasDraw local canvasDraw
major, minor = love.getVersion! major, minor = love.getVersion!
if major == 0 and minor == 10 if major == 0 and minor == 10
canvasDraw = (canvas, x, y) -> canvasDraw = (canvas, x, y) ->
graphics.draw canvas, x, y graphics.draw canvas, x, y
else else
canvasDraw = (canvas, x, y) -> canvasDraw = (canvas, x, y) ->
mode, alpha = graphics.getBlendMode! mode, alpha = graphics.getBlendMode!
graphics.setBlendMode "alpha", "premultiplied" graphics.setBlendMode "alpha", "premultiplied"
graphics.draw canvas, x, y graphics.draw canvas, x, y
graphics.setBlendMode mode, alpha graphics.setBlendMode mode, alpha
-- canvasDraw = (canvas, x, y) -> -- canvasDraw = (canvas, x, y) ->
-- graphics.draw canvas, x, y -- graphics.draw canvas, x, y
class clipRegion extends element class clipRegion extends element
new: (@parent, @data={}) => new: (@parent, @data={}) =>
super @parent, @data super @parent, @data
@data.type = "clipRegion" if @data.type == "element" @data.type = "clipRegion" if @data.type == "element"
@canvas = graphics.newCanvas @data.w, @data.h @canvas = graphics.newCanvas @data.w, @data.h
draw: => draw: =>
graphics.setCanvas @canvas graphics.setCanvas @canvas
graphics.clear! graphics.clear!
recursiveDraw @child, @data.x, @data.y recursiveDraw @child, @data.x, @data.y
graphics.setCanvas! graphics.setCanvas!
graphics.setColor 255, 255, 255, 255 graphics.setColor 255, 255, 255, 255
canvasDraw @canvas, @data.x, @data.y canvasDraw @canvas, @data.x, @data.y
return false return false

View File

@ -3,7 +3,7 @@ import graphics from love
element = require "#{(...)\sub 1, -12}/element" element = require "#{(...)\sub 1, -12}/element"
class dynamicGrid extends element class dynamicGrid extends element
new: (@parent, @data={}) => new: (@parent, @data={}) =>
super @parent, @data super @parent, @data
@data.type = "dynamicGrid" if @data.type == "element" @data.type = "dynamicGrid" if @data.type == "element"

View File

@ -10,302 +10,302 @@ import floor, max from math
import inheritsFromElement from require "#{(...)\sub 1, -19}/util" import inheritsFromElement from require "#{(...)\sub 1, -19}/util"
class element class element
load: (pop_lib) -> load: (pop_lib) ->
pop = pop_lib pop = pop_lib
--- Constructor expects nothing, or a data table describing it. --- Constructor expects nothing, or a data table describing it.
--- @tparam ?Element|false parent The parent element. --- @tparam ?Element|false parent The parent element.
--- @tparam table data[opt] The data (state) for this element. --- @tparam table data[opt] The data (state) for this element.
--- @treturn element self --- @treturn element self
new: (@parent, @data={}) => new: (@parent, @data={}) =>
if type(@data) != "table" if type(@data) != "table"
@data = {} @data = {}
@data.parent = false unless @data.parent @data.parent = false unless @data.parent
@data.child = {} unless @data.child @data.child = {} unless @data.child
@data.type = "element" unless @data.type @data.type = "element" unless @data.type
@data.update = true if @data.update == nil @data.update = true if @data.update == nil
@data.draw = true if @data.draw == nil @data.draw = true if @data.draw == nil
@data.hoverable = true if @data.hoverable == nil @data.hoverable = true if @data.hoverable == nil
-- @data.static = false if @data.static == nil -- @data.static = false if @data.static == nil
unless @data.x
if @parent
@data.x = @parent.data.x
else
@data.x = 0
unless @data.y
if @parent
@data.y = @parent.data.y
else
@data.y = 0
@data.w = 0 unless @data.w
@data.h = 0 unless @data.h
@data.size = 0 unless @data.size
@data.verticalSize = 0 unless @data.verticalSize
@data.horizontalSize = 0 unless @data.horizontalSize
@data.align = true if (@data.align == nil) and @parent
@data.verticalAlign = "top" unless @data.verticalAlign
@data.horizontalAlign = "left" unless @data.horizontalAlign
@data.margin = 0 unless @data.margin
@data.horizontalMargin = 0 unless @data.horizontalMargin
@data.verticalMargin = 0 unless @data.verticalMargin
@data.padding = 0 unless @data.padding
@data.horizontalPadding = 0 unless @data.horizontalPadding
@data.verticalPadding = 0 unless @data.verticalPadding
@child = {}
unless @__class.align -- this is so elements setting up their own alignment (such as window) won't break by alignment being called prematurely
if @data.size != 0 or @data.verticalSize != 0 or @data.horizontalSize != 0
@setSize @parent.data.w * (@data.size + @data.verticalSize), @parent.data.h * (@data.size + @data.horizontalSize)
elseif @data.align
@align!
--- @todo doc me
align: (horizontal, vertical, toPixel=true) =>
unless @data.align return @
@data.horizontalAlign = horizontal if horizontal
@data.verticalAlign = vertical if vertical
unless @data.x
if @parent
@data.x = @parent.data.x @data.x = @parent.data.x
else
@data.x = 0
unless @data.y
if @parent
@data.y = @parent.data.y @data.y = @parent.data.y
else
@data.y = 0
@data.w = 0 unless @data.w
@data.h = 0 unless @data.h
switch @data.horizontalAlign @data.size = 0 unless @data.size
when "left" @data.verticalSize = 0 unless @data.verticalSize
@data.x += max(@parent.data.padding + @parent.data.horizontalPadding, @data.margin + @data.horizontalMargin) @data.horizontalSize = 0 unless @data.horizontalSize
when "center"
@data.x += (@parent.data.w - @data.w) / 2
when "right"
@data.x += @parent.data.w - @data.w - max(@parent.data.padding + @parent.data.horizontalPadding, @data.margin + @data.horizontalMargin)
else
@data.x += @parent.data.w * @data.horizontalAlign
if @data.horizontalAlign < 0
@data.x += @parent.data.w
switch @data.verticalAlign @data.align = true if (@data.align == nil) and @parent
when "top" @data.verticalAlign = "top" unless @data.verticalAlign
@data.y += @parent.data.padding + @data.margin + @data.verticalMargin @data.horizontalAlign = "left" unless @data.horizontalAlign
when "center"
@data.y += (@parent.data.h - @data.h) / 2
when "bottom"
@data.y += @parent.data.h - @data.h - max(@parent.data.padding + @parent.data.verticalPadding, @data.margin + @data.verticalMargin)
else
@data.y += @parent.data.h * @data.verticalAlign
if @data.verticalAlign < 0
@data.y += @parent.data.h
if toPixel @data.margin = 0 unless @data.margin
@data.x = floor @data.x @data.horizontalMargin = 0 unless @data.horizontalMargin
@data.y = floor @data.y @data.verticalMargin = 0 unless @data.verticalMargin
return @ @data.padding = 0 unless @data.padding
@data.horizontalPadding = 0 unless @data.horizontalPadding
@data.verticalPadding = 0 unless @data.verticalPadding
--- @todo document this @child = {}
setPosition: (x, y, toPixel=true) =>
dx, dy = @data.x, @data.y
if x
@data.x = x
switch @data.horizontalAlign
when "center"
@data.x -= @data.w / 2
when "right"
@data.x -= @data.w
if y
@data.y = y
switch @data.verticalAlign
when "center"
@data.y -= @data.h / 2
when "bottom"
@data.y -= @data.h
if toPixel
@data.x = floor @data.x
@data.y = floor @data.y
-- new minus old is difference that children need to be moved
dx = @data.x - dx
dy = @data.y - dy
for child in *@child
child\move dx, dy
return @
--- @todo doc me
getPosition: =>
x, y = @data.x, @data.y
switch @data.horizontalAlign
when "center"
x += @data.w / 2
when "right"
y += @data.w
switch @data.verticalAlign
when "center"
y += @data.h / 2
when "bottom"
y += @data.h
return x, y
--- Sets an element's width/height. Fixes alignment if needed.
--- @tparam integer w[opt] Width.
--- @tparam integer h[opt] Height.
--- @treturn element self
setSize: (w, h) =>
if w
@data.w = w
if h
@data.h = h
unless @__class.align -- this is so elements setting up their own alignment (such as window) won't break by alignment being called prematurely
if @data.size != 0 or @data.verticalSize != 0 or @data.horizontalSize != 0
@setSize @parent.data.w * (@data.size + @data.verticalSize), @parent.data.h * (@data.size + @data.horizontalSize)
elseif @data.align
@align! @align!
--- @todo doc me
align: (horizontal, vertical, toPixel=true) =>
unless @data.align return @
@data.horizontalAlign = horizontal if horizontal
@data.verticalAlign = vertical if vertical
@data.x = @parent.data.x
@data.y = @parent.data.y
switch @data.horizontalAlign
when "left"
@data.x += max(@parent.data.padding + @parent.data.horizontalPadding, @data.margin + @data.horizontalMargin)
when "center"
@data.x += (@parent.data.w - @data.w) / 2
when "right"
@data.x += @parent.data.w - @data.w - max(@parent.data.padding + @parent.data.horizontalPadding, @data.margin + @data.horizontalMargin)
else
@data.x += @parent.data.w * @data.horizontalAlign
if @data.horizontalAlign < 0
@data.x += @parent.data.w
switch @data.verticalAlign
when "top"
@data.y += @parent.data.padding + @data.margin + @data.verticalMargin
when "center"
@data.y += (@parent.data.h - @data.h) / 2
when "bottom"
@data.y += @parent.data.h - @data.h - max(@parent.data.padding + @parent.data.verticalPadding, @data.margin + @data.verticalMargin)
else
@data.y += @parent.data.h * @data.verticalAlign
if @data.verticalAlign < 0
@data.y += @parent.data.h
if toPixel
@data.x = floor @data.x
@data.y = floor @data.y
return @
--- @todo document this
setPosition: (x, y, toPixel=true) =>
dx, dy = @data.x, @data.y
if x
@data.x = x
switch @data.horizontalAlign
when "center"
@data.x -= @data.w / 2
when "right"
@data.x -= @data.w
if y
@data.y = y
switch @data.verticalAlign
when "center"
@data.y -= @data.h / 2
when "bottom"
@data.y -= @data.h
if toPixel
@data.x = floor @data.x
@data.y = floor @data.y
-- new minus old is difference that children need to be moved
dx = @data.x - dx
dy = @data.y - dy
for child in *@child
child\move dx, dy
return @
--- @todo doc me
getPosition: =>
x, y = @data.x, @data.y
switch @data.horizontalAlign
when "center"
x += @data.w / 2
when "right"
y += @data.w
switch @data.verticalAlign
when "center"
y += @data.h / 2
when "bottom"
y += @data.h
return x, y
--- Sets an element's width/height. Fixes alignment if needed.
--- @tparam integer w[opt] Width.
--- @tparam integer h[opt] Height.
--- @treturn element self
setSize: (w, h) =>
if w
@data.w = w
if h
@data.h = h
@align!
return @
--- Returns an element's width and height.
--- @treturn integer Width.
--- @treturn integer Height.
getSize: =>
return @data.w, @data.h
--- Sets an element's width.
--- @tparam integer w Width.
--- @treturn element self
setWidth: (w) =>
@data.w = w
@align!
return @
--- Returns an element's width.
--- @treturn integer Width.
getWidth: =>
return @data.w
--- Sets an element's height.
--- @tparam integer h Height.
--- @treturn element self
setHeight: (h) =>
@data.h = h
@align!
return @
--- Returns an element's height.
--- @treturn integer Height.
getHeight: =>
return @data.h
--- @todo doc me
adjustSize: (w, h) =>
W, H = @getSize!
if w
W += w
if h
H += h
@setSize W, H
return @
--- Moves an element by specified x/y.
--- @treturn element self
move: (x=0, y=0) =>
--if @data.static return @
@data.x += x
@data.y += y
for child in *@child
child\move x, y
return @
setPadding: (padding) =>
@data.padding = padding
@align!
return @
getPadding: =>
return @data.padding
setMargin: (margin) =>
@data.margin = margin
@align!
return @
getMargin: =>
return @data.margin
indexOf: (element) =>
for i = 1, #@child
if @child[i] == element
return i
dataIndexOf: (data) =>
for i = 1, #@data.child
if @data.child[i] == data
return i
add: (element) =>
unless inheritsFromElement element
for e in *element
@add e
return @ return @
--- Returns an element's width and height. element.parent\remove(element)
--- @treturn integer Width.
--- @treturn integer Height.
getSize: =>
return @data.w, @data.h
--- Sets an element's width. table.insert @child, element
--- @tparam integer w Width. table.insert @data.child, element.data
--- @treturn element self
setWidth: (w) => return @
@data.w = w
@align! remove: (element) =>
unless inheritsFromElement element
for e in *element
@remove e
return @ return @
--- Returns an element's width. index = @indexOf element
--- @treturn integer Width. dataIndex = @dataIndexOf element.data
getWidth: =>
return @data.w
--- Sets an element's height. table.remove @child, index
--- @tparam integer h Height. table.remove @data.child, dataIndex
--- @treturn element self
setHeight: (h) =>
@data.h = h
@align!
return @
--- Returns an element's height. return @
--- @treturn integer Height.
getHeight: =>
return @data.h
--- @todo doc me --- Deletes references to this element and then deletes it.
adjustSize: (w, h) => delete: =>
W, H = @getSize! -- does not work for desired issue, element is still referenced and set as focused after this would be called
-- however, it is probably a good idea for anything being deleted to make sure it isn't focused
if @ == pop.hovered
pop.hovered = false
pop.log "#{@} (#{@type}) unfocused (deleted)"
if w for i=#@child, 1, -1
W += w @child[i]\delete!
if h
H += h
@setSize W, H if @parent
for i=1, #@parent.child
if @parent.child[i] == @
table.remove @parent.child, i
break
return @ if @parent
for i=1, #@parent.data.child
if @parent.data.child[i] == @data
table.remove @parent.data.child, i
break
--- Moves an element by specified x/y. @parent = nil
--- @treturn element self @data.parent = nil -- should be for all @ -> nil MAYBE
move: (x=0, y=0) => @ = nil
--if @data.static return @ -- DO NOT DELETE @data though, it could still be in use
@data.x += x
@data.y += y
for child in *@child
child\move x, y
return @
setPadding: (padding) =>
@data.padding = padding
@align!
return @
getPadding: =>
return @data.padding
setMargin: (margin) =>
@data.margin = margin
@align!
return @
getMargin: =>
return @data.margin
indexOf: (element) =>
for i = 1, #@child
if @child[i] == element
return i
dataIndexOf: (data) =>
for i = 1, #@data.child
if @data.child[i] == data
return i
add: (element) =>
unless inheritsFromElement element
for e in *element
@add e
return @
element.parent\remove(element)
table.insert @child, element
table.insert @data.child, element.data
return @
remove: (element) =>
unless inheritsFromElement element
for e in *element
@remove e
return @
index = @indexOf element
dataIndex = @dataIndexOf element.data
table.remove @child, index
table.remove @data.child, dataIndex
return @
--- Deletes references to this element and then deletes it.
delete: =>
-- does not work for desired issue, element is still referenced and set as focused after this would be called
-- however, it is probably a good idea for anything being deleted to make sure it isn't focused
if @ == pop.hovered
pop.hovered = false
pop.log "#{@} (#{@type}) unfocused (deleted)"
for i=#@child, 1, -1
@child[i]\delete!
if @parent
for i=1, #@parent.child
if @parent.child[i] == @
table.remove @parent.child, i
break
if @parent
for i=1, #@parent.data.child
if @parent.data.child[i] == @data
table.remove @parent.data.child, i
break
@parent = nil
@data.parent = nil -- should be for all @ -> nil MAYBE
@ = nil
-- DO NOT DELETE @data though, it could still be in use

View File

@ -3,7 +3,7 @@ import graphics from love
element = require "#{(...)\sub 1, -5}/element" element = require "#{(...)\sub 1, -5}/element"
class grid extends element class grid extends element
new: (@parent, @data={}) => new: (@parent, @data={}) =>
super @parent, @data super @parent, @data
@data.type = "grid" if @data.type == "element" @data.type = "grid" if @data.type == "element"

View File

@ -3,7 +3,7 @@ import graphics from love
element = require "#{(...)\sub 1, -10}/element" element = require "#{(...)\sub 1, -10}/element"
class scrollbox extends element class scrollbox extends element
new: (@parent, @data={}) => new: (@parent, @data={}) =>
super @parent, @data super @parent, @data
@data.type = "scrollbox" if @data.type == "element" @data.type = "scrollbox" if @data.type == "element"

View File

@ -8,69 +8,69 @@ import graphics from love
element = require "#{(...)\sub 1, -5}/element" element = require "#{(...)\sub 1, -5}/element"
class text extends element class text extends element
--- Constructor expects nothing, or a data table describing it. --- Constructor expects nothing, or a data table describing it.
new: (@parent, @data={}, text="", fontFile, fontSize=14) => new: (@parent, @data={}, text="", fontFile, fontSize=14) =>
super @parent, @data super @parent, @data
-- this makes text optional, a number can be passed to set font size immediately -- this makes text optional, a number can be passed to set font size immediately
if "number" == type text if "number" == type text
fontSize = fontFile fontSize = fontFile
fontFile = text fontFile = text
text = "" text = ""
@data.type = "text" if @data.type == "element" @data.type = "text" if @data.type == "element"
@data.text = text unless @data.text @data.text = text unless @data.text
@data.fontFile = fontFile unless @data.fontFile @data.fontFile = fontFile unless @data.fontFile
@data.fontSize = fontSize unless @data.fontSize @data.fontSize = fontSize unless @data.fontSize
@data.color = {255, 255, 255, 255} unless @data.color @data.color = {255, 255, 255, 255} unless @data.color
if "string" == type @data.fontFile if "string" == type @data.fontFile
@font = graphics.newFont(@data.fontFile, @data.fontSize) @font = graphics.newFont(@data.fontFile, @data.fontSize)
elseif "number" == type @data.fontFile elseif "number" == type @data.fontFile
@font = graphics.newFont(@data.fontFile) @font = graphics.newFont(@data.fontFile)
else else
@font = graphics.newFont(@data.fontSize) @font = graphics.newFont(@data.fontSize)
@setSize! @setSize!
draw: => draw: =>
graphics.setColor(@data.color) graphics.setColor(@data.color)
graphics.setFont(@font) graphics.setFont(@font)
graphics.print(@data.text, @data.x, @data.y) graphics.print(@data.text, @data.x, @data.y)
return @ return @
--- Size is dependant on the text and font, so you cannot specify a size. --- Size is dependant on the text and font, so you cannot specify a size.
--- @treturn element self --- @treturn element self
setSize: => setSize: =>
@data.w = @font\getWidth @data.text @data.w = @font\getWidth @data.text
@data.h = @font\getHeight! * (select(2, @data.text\gsub("\n", "\n")) + 1) --hack to get height of multiple lines @data.h = @font\getHeight! * (select(2, @data.text\gsub("\n", "\n")) + 1) --hack to get height of multiple lines
return @ return @
--- Returns text. --- Returns text.
--- @treturn string text --- @treturn string text
getText: => getText: =>
return @data.text return @data.text
--- Text should be set this way, or the object will not be the correct size. --- Text should be set this way, or the object will not be the correct size.
--- @tparam string text The text to set. --- @tparam string text The text to set.
--- @treturn element self --- @treturn element self
setText: (text) => setText: (text) =>
@data.text = tostring text @data.text = tostring text
@setSize! @setSize!
return @align! return @align!
--- Change text color. Uses LOVE's 0-255 values for components of colors. --- Change text color. Uses LOVE's 0-255 values for components of colors.
--- @tparam ?number|table r The red component or a table of RGBA values. --- @tparam ?number|table r The red component or a table of RGBA values.
--- @tparam number g The green component. --- @tparam number g The green component.
--- @tparam number b The blue component. --- @tparam number b The blue component.
--- @tparam number a The alpha component. While not technically required, if --- @tparam number a The alpha component. While not technically required, if
--- ANYTHING uses an alpha component and you don't, it could cause bugs in --- ANYTHING uses an alpha component and you don't, it could cause bugs in
--- rendering. --- rendering.
--- @treturn element self --- @treturn element self
setColor: (r, g, b, a) => setColor: (r, g, b, a) =>
if "table" == type r if "table" == type r
@data.color = r @data.color = r
else else
@data.color = {r, g, b, a} @data.color = {r, g, b, a}
return @ return @

View File

@ -21,291 +21,291 @@ closeImage = graphics.newImage "#{path}/images/close.png"
-- drag to resize is based on area of padding, which defaults to 5 pixels -- drag to resize is based on area of padding, which defaults to 5 pixels
class window extends element class window extends element
load: (pop_lib) -> load: (pop_lib) ->
pop = pop_lib pop = pop_lib
--- Constructor expects nothing, or a data table describing it. --- Constructor expects nothing, or a data table describing it.
--- @todo document containMethod values --- @todo document containMethod values
new: (@parent, @data={}, title="Window") => new: (@parent, @data={}, title="Window") =>
super @parent, @data super @parent, @data
@data.type = "window" if @data.type == "element" @data.type = "window" if @data.type == "element"
@data.w = 100 unless @data.w > 0 @data.w = 100 unless @data.w > 0
@data.h = 80 unless @data.h > 0 @data.h = 80 unless @data.h > 0
-- how a window is contained within its parent element -- how a window is contained within its parent element
@data.containMethod = "mouse" unless @data.containMethod @data.containMethod = "mouse" unless @data.containMethod
@data.maximized = false @data.maximized = false
@data.titleBar = true if @data.titleBar == nil @data.titleBar = true if @data.titleBar == nil
@data.moveable = true if @data.moveable == nil @data.moveable = true if @data.moveable == nil
@data.maximizeable = false if @data.maximizeable == nil @data.maximizeable = false if @data.maximizeable == nil
@data.minimizeable = false if @data.minimizeable == nil @data.minimizeable = false if @data.minimizeable == nil
@data.closeable = false if @data.closeable == nil @data.closeable = false if @data.closeable == nil
unless @data.previous unless @data.previous
@data.previous = {} @data.previous = {}
@header = pop.box @, {type: "box (window header)"}, @data.titleBackground or {25, 180, 230, 255} @header = pop.box @, {type: "box (window header)"}, @data.titleBackground or {25, 180, 230, 255}
@title = pop.text @header, {horizontal: "center", type: "text (window title)"}, title, @data.titleColor or {255, 255, 255, 255} @title = pop.text @header, {horizontal: "center", type: "text (window title)"}, title, @data.titleColor or {255, 255, 255, 255}
@window_area = pop.box @, {padding: 5, type: "box (window area)"}, @data.windowBackground or {200, 200, 210, 255} @window_area = pop.box @, {padding: 5, type: "box (window area)"}, @data.windowBackground or {200, 200, 210, 255}
-- buttons! :D -- buttons! :D
@data.header_width_reduction = 0 @data.header_width_reduction = 0
buttonSize = @title\getHeight! + 1 buttonSize = @title\getHeight! + 1
if @data.closeable if @data.closeable
@closeButton = pop.box(@, {w: buttonSize, h: buttonSize, horizontalMargin: @data.header_width_reduction, type: "box (window close button)"}, closeImage)\align "right" @closeButton = pop.box(@, {w: buttonSize, h: buttonSize, horizontalMargin: @data.header_width_reduction, type: "box (window close button)"}, closeImage)\align "right"
@closeButton.clicked = (x, y, button) => @closeButton.clicked = (x, y, button) =>
if button == pop.constants.left_mouse if button == pop.constants.left_mouse
@parent\close! @parent\close!
return true return true
@data.header_width_reduction += buttonSize @data.header_width_reduction += buttonSize
if @data.maximizeable if @data.maximizeable
@maximizeButton = pop.box(@, {w: buttonSize, h: buttonSize, horizontalMargin: @data.header_width_reduction, type: "box (window maximize button)"}, maximizeImage)\align "right" @maximizeButton = pop.box(@, {w: buttonSize, h: buttonSize, horizontalMargin: @data.header_width_reduction, type: "box (window maximize button)"}, maximizeImage)\align "right"
@maximizeButton.clicked = (x, y, button) => @maximizeButton.clicked = (x, y, button) =>
if button == pop.constants.left_mouse if button == pop.constants.left_mouse
@parent\maximize! @parent\maximize!
return true return true
@data.header_width_reduction += buttonSize @data.header_width_reduction += buttonSize
if @data.minimizeable if @data.minimizeable
@minimizeButton = pop.box(@, {w: buttonSize, h: buttonSize, horizontalMargin: @data.header_width_reduction, type: "box (window minimize button)"}, minimizeImage)\align "right" @minimizeButton = pop.box(@, {w: buttonSize, h: buttonSize, horizontalMargin: @data.header_width_reduction, type: "box (window minimize button)"}, minimizeImage)\align "right"
@minimizeButton.clicked = (x, y, button) => @minimizeButton.clicked = (x, y, button) =>
if button == pop.constants.left_mouse if button == pop.constants.left_mouse
@parent\minimize! @parent\minimize!
return true return true
@data.header_width_reduction += buttonSize @data.header_width_reduction += buttonSize
height = @title\getHeight! + 1 height = @title\getHeight! + 1
@header\setSize @data.w - @data.header_width_reduction, height @header\setSize @data.w - @data.header_width_reduction, height
if @data.titleBar if @data.titleBar
@window_area\setSize @data.w, @data.h - height @window_area\setSize @data.w, @data.h - height
@window_area\move nil, height @window_area\move nil, height
else else
@header.data.draw = false @header.data.draw = false
@window_area.data.x = @data.x + @data.padding @window_area.data.x = @data.x + @data.padding
@window_area.data.y = @data.y + @data.padding @window_area.data.y = @data.y + @data.padding
@window_area.data.w = @data.w - @data.padding*2 @window_area.data.w = @data.w - @data.padding*2
@window_area.data.h = @data.h - @data.padding*2 @window_area.data.h = @data.h - @data.padding*2
-- window area steals mouse events to prevent propagation to elements visibily underneath it (not within its hierarchy) -- window area steals mouse events to prevent propagation to elements visibily underneath it (not within its hierarchy)
@window_area.mousepressed = (x, y, button) => @window_area.mousepressed = (x, y, button) =>
if button == pop.constants.left_mouse if button == pop.constants.left_mouse
grandparent = @parent.parent grandparent = @parent.parent
table.insert grandparent.child, table.remove(grandparent.child, grandparent\indexOf @parent) table.insert grandparent.child, table.remove(grandparent.child, grandparent\indexOf @parent)
return nil return nil
@window_area.clicked = => @window_area.clicked = =>
return nil return nil
-- @window_area.add = (element) => -- @window_area.add = (element) =>
-- pop.elements.box.__parent.add @, element -- pop.elements.box.__parent.add @, element
-- --NOTE temporarily disabled -- --NOTE temporarily disabled
-- -- this seems to be working but errors with previous == nil -- -- this seems to be working but errors with previous == nil
-- -- I have moved the intended functionality to the window element's function that calls these -- -- I have moved the intended functionality to the window element's function that calls these
-- if false and inheritsFromElement element -- if false and inheritsFromElement element
-- -- we need to adjust its position based on the previous element -- -- we need to adjust its position based on the previous element
-- previous = @data.child[#@data.child-1] -- previous = @data.child[#@data.child-1]
-- y, h = previous.y, previous.h -- y, h = previous.y, previous.h
-- y += h + @data.padding -- y += h + @data.padding
-- element.data.x = @data.x + @data.padding -- element.data.x = @data.x + @data.padding
-- element.data.y = y -- element.data.y = y
-- element\setWidth @data.w - @data.padding*2 -- element\setWidth @data.w - @data.padding*2
-- --
-- @window_area.remove = (element) => -- @window_area.remove = (element) =>
-- pop.elements.box.__parent.remove @, element -- pop.elements.box.__parent.remove @, element
-- --TODO we need to adjust all elements' positions -- --TODO we need to adjust all elements' positions
selected = false
mx = 0
my = 0
@header.mousemoved = (x, y, dx, dy) =>
if selected
@parent\move dx, dy
-- do not leave area of grandparent (based on containMethod)
grandparent = @parent.parent
switch @parent.data.containMethod
when "title" -- the window title can't leave
@parent\move(grandparent.data.x - @data.x) if @data.x < grandparent.data.x
@parent\move(nil, grandparent.data.y - @data.y) if @data.y < grandparent.data.y
@parent\move(grandparent.data.x + grandparent.data.w - (@data.x + @data.w)) if @data.x + @data.w > grandparent.data.x + grandparent.data.w
@parent\move(nil, grandparent.data.y + grandparent.data.h - (@data.y + @data.h)) if @data.y + @data.h > grandparent.data.y + grandparent.data.h
when "body" -- the entire window can't leave
@parent\move(grandparent.data.x - @data.x) if @data.x < grandparent.data.x
@parent\move(nil, grandparent.data.y - @data.y) if @data.y < grandparent.data.y
@parent\move(grandparent.data.x + grandparent.data.w - (@parent.data.x + @parent.data.w)) if @parent.data.x + @parent.data.w > grandparent.data.x + grandparent.data.w
@parent\move(nil, grandparent.data.y + grandparent.data.h - (@parent.data.y + @parent.data.h)) if @parent.data.y + @parent.data.h > grandparent.data.y + grandparent.data.h
when "mouse" -- wherever the mouse has clicked can't leave
@parent\setPosition(grandparent.data.x + @data.w - mx) if mouse.getX! < grandparent.data.x
@parent\setPosition(nil, grandparent.data.y + @parent.data.h - my) if mouse.getY! < grandparent.data.y
@parent\setPosition(grandparent.data.x + grandparent.data.w + @data.w - mx) if mouse.getX! > grandparent.data.x + grandparent.data.w
@parent\setPosition(nil, grandparent.data.y + grandparent.data.h + @parent.data.h - my) if mouse.getY! > grandparent.data.y + grandparent.data.h
return true
return false
@header.mousepressed = (x, y, button) =>
if button == pop.constants.left_mouse and @parent.data.moveable
grandparent = @parent.parent
table.insert grandparent.child, table.remove(grandparent.child, grandparent\indexOf @parent)
selected = true
mx = x
my = y
return true
return false
@header.mousereleased = (x, y, button) =>
if button == pop.constants.left_mouse
selected = false selected = false
mx = 0 if @ == pop.focused
my = 0 pop.focused = false
return true
return false
@header.mousemoved = (x, y, dx, dy) => if @data.size != 0 or @data.verticalSize != 0 or @data.horizontalSize != 0
if selected @setSize @parent.data.w * (@data.size + @data.verticalSize), @parent.data.h * (@data.size + @data.horizontalSize)
@parent\move dx, dy elseif @data.align
-- do not leave area of grandparent (based on containMethod) @align!
grandparent = @parent.parent
switch @parent.data.containMethod
when "title" -- the window title can't leave
@parent\move(grandparent.data.x - @data.x) if @data.x < grandparent.data.x
@parent\move(nil, grandparent.data.y - @data.y) if @data.y < grandparent.data.y
@parent\move(grandparent.data.x + grandparent.data.w - (@data.x + @data.w)) if @data.x + @data.w > grandparent.data.x + grandparent.data.w
@parent\move(nil, grandparent.data.y + grandparent.data.h - (@data.y + @data.h)) if @data.y + @data.h > grandparent.data.y + grandparent.data.h
when "body" -- the entire window can't leave
@parent\move(grandparent.data.x - @data.x) if @data.x < grandparent.data.x
@parent\move(nil, grandparent.data.y - @data.y) if @data.y < grandparent.data.y
@parent\move(grandparent.data.x + grandparent.data.w - (@parent.data.x + @parent.data.w)) if @parent.data.x + @parent.data.w > grandparent.data.x + grandparent.data.w
@parent\move(nil, grandparent.data.y + grandparent.data.h - (@parent.data.y + @parent.data.h)) if @parent.data.y + @parent.data.h > grandparent.data.y + grandparent.data.h
when "mouse" -- wherever the mouse has clicked can't leave
@parent\setPosition(grandparent.data.x + @data.w - mx) if mouse.getX! < grandparent.data.x
@parent\setPosition(nil, grandparent.data.y + @parent.data.h - my) if mouse.getY! < grandparent.data.y
@parent\setPosition(grandparent.data.x + grandparent.data.w + @data.w - mx) if mouse.getX! > grandparent.data.x + grandparent.data.w
@parent\setPosition(nil, grandparent.data.y + grandparent.data.h + @parent.data.h - my) if mouse.getY! > grandparent.data.y + grandparent.data.h
return true
return false
@header.mousepressed = (x, y, button) => align: (...) =>
if button == pop.constants.left_mouse and @parent.data.moveable unless @data.align return @
grandparent = @parent.parent super ...
table.insert grandparent.child, table.remove(grandparent.child, grandparent\indexOf @parent)
selected = true
mx = x
my = y
return true
return false
@header.mousereleased = (x, y, button) => @header\align!
if button == pop.constants.left_mouse @title\align!
selected = false @window_area\align!
if @ == pop.focused if @closeButton
pop.focused = false @closeButton\align!
return true if @maximizeButton
return false @maximizeButton\align!
if @minimizeButton
@minimizeButton\align!
if @data.size != 0 or @data.verticalSize != 0 or @data.horizontalSize != 0 if @data.titleBar
@setSize @parent.data.w * (@data.size + @data.verticalSize), @parent.data.h * (@data.size + @data.horizontalSize) @window_area\move nil, @header\getHeight!
elseif @data.align
@align!
align: (...) => return @
unless @data.align return @
super ...
@header\align! setSize: (w, h) =>
@title\align! x = 0
@window_area\align! y = 0
if @closeButton
@closeButton\align!
if @maximizeButton
@maximizeButton\align!
if @minimizeButton
@minimizeButton\align!
if @data.titleBar if w
@window_area\move nil, @header\getHeight! switch @data.horizontalAlign
when "left"
return @ local _ -- do nothing
when "center"
setSize: (w, h) => x -= (w - @data.w) / 2
x = 0 when "right"
y = 0 x -= w - @data.w
if w
switch @data.horizontalAlign
when "left"
local _ -- do nothing
when "center"
x -= (w - @data.w) / 2
when "right"
x -= w - @data.w
else
if @data.horizontalAlign < 0
x -= w - @data.w
@header\setWidth w - @data.header_width_reduction
@window_area\setWidth w
@data.w = w
@data.x += x
@title\align!
if h
switch @data.verticalAlign
when "top"
local _ -- do nothing
when "center"
y -= (h - @data.h) / 2
when "bottom"
y -= h - @data.h
else
if @data.horizontalAlign < 0
y -= h - @data.h
if @data.titleBar
@window_area\setHeight h - @header\getHeight!
@window_area\move nil, @header\getHeight!
else
@window_area\setHeight h
@data.h = h
@data.y += y
@header\move x, y
@window_area\move x, y
return @
setWidth: (w) =>
return @setSize w
setHeight: (h) =>
return @setSize nil, h
setPadding: (padding) =>
@window_area\setPadding padding
return @
getPadding: =>
return @window_area\getPadding!
add: (element) =>
@window_area\add element
x, y = @window_area.data.x, @window_area.data.y
--for element in *@window_area.child
--element\setWidth @data.w - @data.padding*2
--TODO needs to align them vertically with appropriate padding (I am not taking margin into account which is bad)
return @
-- @window_area.add = (element) =>
-- pop.elements.box.__parent.add @, element
-- --NOTE temporarily disabled
-- -- this seems to be working but errors with previous == nil
-- -- I have moved the intended functionality to the window element's function that calls these
-- if false and inheritsFromElement element
-- -- we need to adjust its position based on the previous element
-- previous = @data.child[#@data.child-1]
-- y, h = previous.y, previous.h
-- y += h + @data.padding
-- element.data.x = @data.x + @data.padding
-- element.data.y = y
-- element\setWidth @data.w - @data.padding*2
--
-- @window_area.remove = (element) =>
-- pop.elements.box.__parent.remove @, element
-- --TODO we need to adjust all elements' positions
remove: (element) =>
@window_area\remove element
return @
--NOTE was this even used?
--childAdded: (element) =>
-- table.insert @window_area.data, table.remove @data.child, @dataIndexOf element.data
-- table.insert @window_area, table.remove @child, @indexOf element
-- element\align!
-- print "worked?"
-- return @
maximize: =>
if @data.maximized
@setSize @data.previous.w, @data.previous.h
@align!
@move @data.previous.x - @data.x, @data.previous.y - @data.y
else else
@data.previous.x = @data.x if @data.horizontalAlign < 0
@data.previous.y = @data.y x -= w - @data.w
@data.previous.w = @data.w
@data.previous.h = @data.h
@data.x = @parent.data.x
@data.y = @parent.data.y
@setSize @parent.data.w, @parent.data.h
table.insert @parent.child, table.remove(@parent.child, @parent\indexOf @)
@align!
@data.maximized = not @data.maximized
return @
minimize: => @header\setWidth w - @data.header_width_reduction
@data.draw = false @window_area\setWidth w
return @ @data.w = w
@data.x += x
close: => @title\align!
@delete!
if h
switch @data.verticalAlign
when "top"
local _ -- do nothing
when "center"
y -= (h - @data.h) / 2
when "bottom"
y -= h - @data.h
else
if @data.horizontalAlign < 0
y -= h - @data.h
if @data.titleBar
@window_area\setHeight h - @header\getHeight!
@window_area\move nil, @header\getHeight!
else
@window_area\setHeight h
@data.h = h
@data.y += y
@header\move x, y
@window_area\move x, y
return @
setWidth: (w) =>
return @setSize w
setHeight: (h) =>
return @setSize nil, h
setPadding: (padding) =>
@window_area\setPadding padding
return @
getPadding: =>
return @window_area\getPadding!
add: (element) =>
@window_area\add element
x, y = @window_area.data.x, @window_area.data.y
--for element in *@window_area.child
--element\setWidth @data.w - @data.padding*2
--TODO needs to align them vertically with appropriate padding (I am not taking margin into account which is bad)
return @
-- @window_area.add = (element) =>
-- pop.elements.box.__parent.add @, element
-- --NOTE temporarily disabled
-- -- this seems to be working but errors with previous == nil
-- -- I have moved the intended functionality to the window element's function that calls these
-- if false and inheritsFromElement element
-- -- we need to adjust its position based on the previous element
-- previous = @data.child[#@data.child-1]
-- y, h = previous.y, previous.h
-- y += h + @data.padding
-- element.data.x = @data.x + @data.padding
-- element.data.y = y
-- element\setWidth @data.w - @data.padding*2
--
-- @window_area.remove = (element) =>
-- pop.elements.box.__parent.remove @, element
-- --TODO we need to adjust all elements' positions
remove: (element) =>
@window_area\remove element
return @
--NOTE was this even used?
--childAdded: (element) =>
-- table.insert @window_area.data, table.remove @data.child, @dataIndexOf element.data
-- table.insert @window_area, table.remove @child, @indexOf element
-- element\align!
-- print "worked?"
-- return @
maximize: =>
if @data.maximized
@setSize @data.previous.w, @data.previous.h
@align!
@move @data.previous.x - @data.x, @data.previous.y - @data.y
else
@data.previous.x = @data.x
@data.previous.y = @data.y
@data.previous.w = @data.w
@data.previous.h = @data.h
@data.x = @parent.data.x
@data.y = @parent.data.y
@setSize @parent.data.w, @parent.data.h
table.insert @parent.child, table.remove(@parent.child, @parent\indexOf @)
@align!
@data.maximized = not @data.maximized
return @
minimize: =>
@data.draw = false
return @
close: =>
@delete!

639
init.moon
View File

@ -5,25 +5,25 @@
--- @release 0.0.0 --- @release 0.0.0
pop = { pop = {
_VERSION: '0.0.0' _VERSION: '0.0.0'
_DESCRIPTION: 'GUI library for LOVE, designed for ease of use' _DESCRIPTION: 'GUI library for LOVE, designed for ease of use'
_URL: 'http://github.com/Guard13007/Pop.Box' _URL: 'http://github.com/Guard13007/Pop.Box'
_LICENSE: 'The MIT License (MIT)' _LICENSE: 'The MIT License (MIT)'
_AUTHOR: 'Paul Liverman III' _AUTHOR: 'Paul Liverman III'
} }
log = (...) -> log = (...) ->
print "[Pop.Box]", ... print "[Pop.Box]", ...
unless love.getVersion unless love.getVersion
error "Pop.Box only supports LOVE versions >= 0.9.1" error "Pop.Box only supports LOVE versions >= 0.9.1"
path = (...)\gsub "%.", "/" path = (...)\gsub "%.", "/"
if (...)\sub(-4) == "init" if (...)\sub(-4) == "init"
path = (...)\sub 1, -5 path = (...)\sub 1, -5
unless path unless path
path = "." path = "."
log "Require path detected: \"#{path}\"" log "Require path detected: \"#{path}\""
@ -49,29 +49,29 @@ import dumps, loads from require "#{path}/lib/bitser/bitser"
major, minor, revision = love.getVersion! major, minor, revision = love.getVersion!
if major == 0 and minor == 9 if major == 0 and minor == 9
pop.constants = { pop.constants = {
left_mouse: "l" left_mouse: "l"
middle_mouse: "m" middle_mouse: "m"
right_mouse: "r" right_mouse: "r"
button_4: "x1" button_4: "x1"
button_5: "x2" button_5: "x2"
-- note: these should not be used -- note: these should not be used
mouse_wheel_down: "wd" mouse_wheel_down: "wd"
mouse_wheel_up: "wu" mouse_wheel_up: "wu"
} }
elseif major == 0 and minor == 10 elseif major == 0 and minor == 10
pop.constants = { pop.constants = {
left_mouse: 1 left_mouse: 1
middle_mouse: 3 middle_mouse: 3
right_mouse: 2 right_mouse: 2
button_4: 4 button_4: 4
button_5: 5 button_5: 5
--no mouse wheel, may lead to problems? -- no mouse wheel, may lead to problems?
} }
else else
pop.constants = {} -- this would be an unsupported version currently pop.constants = {} -- this would be an unsupported version currently
pop.elements = {} pop.elements = {}
pop.skins = {} pop.skins = {}
@ -98,109 +98,109 @@ pop.log = log
--- @todo @ see Skins, see Extensions --- @todo @ see Skins, see Extensions
pop.load = (load_path=path) -> pop.load = (load_path=path) ->
log "Loading elements from \"#{load_path}/elements\"" log "Loading elements from \"#{load_path}/elements\""
elements = filesystem.getDirectoryItems "#{load_path}/elements" elements = filesystem.getDirectoryItems "#{load_path}/elements"
for i = 1, #elements for i = 1, #elements
-- ignore non-Lua files -- ignore non-Lua files
unless elements[i]\sub(-4) == ".lua" unless elements[i]\sub(-4) == ".lua"
log "Ignored non-Lua file \"#{load_path}/elements/#{elements[i]}\"" log "Ignored non-Lua file \"#{load_path}/elements/#{elements[i]}\""
continue continue
-- require into pop.elements table by filename -- require into pop.elements table by filename
name = elements[i]\sub 1, -5 name = elements[i]\sub 1, -5
log "Requiring \"#{name}\" from \"#{load_path}/elements/#{name}\"" log "Requiring \"#{name}\" from \"#{load_path}/elements/#{name}\""
pop.elements[name] = require "#{load_path}/elements/#{name}" pop.elements[name] = require "#{load_path}/elements/#{name}"
-- call the element's load function if it exists -- call the element's load function if it exists
if pop.elements[name].load if pop.elements[name].load
pop.elements[name].load pop pop.elements[name].load pop
log "Element loaded: \"#{name}\"" log "Element loaded: \"#{name}\""
-- create "pop.element()" function wrapper if possible -- create "pop.element()" function wrapper if possible
unless pop[name] unless pop[name]
if pop.elements[name].wrap if pop.elements[name].wrap
pop[name] = pop.elements[name].wrap pop pop[name] = pop.elements[name].wrap pop
else else
pop[name] = (...) -> pop[name] = (...) ->
return pop.create(name, ...) return pop.create(name, ...)
log "Wrapper created: \"pop.#{name}()\"" log "Wrapper created: \"pop.#{name}()\""
skins = filesystem.getDirectoryItems "#{load_path}/skins" skins = filesystem.getDirectoryItems "#{load_path}/skins"
for i = 1, #skins for i = 1, #skins
-- ignore non-Lua files -- ignore non-Lua files
unless skins[i]\sub(-4) == ".lua" unless skins[i]\sub(-4) == ".lua"
log "Ignored non-Lua file \"#{load_path}/skins/#{skins[i]}\"" log "Ignored non-Lua file \"#{load_path}/skins/#{skins[i]}\""
continue continue
-- require into pop.skins table by filename -- require into pop.skins table by filename
name = skins[i]\sub 1, -5 name = skins[i]\sub 1, -5
log "Requiring \"#{name}\" from \"#{load_path}/skins/#{name}\"" log "Requiring \"#{name}\" from \"#{load_path}/skins/#{name}\""
pop.skins[name] = require "#{load_path}/skins/#{name}" pop.skins[name] = require "#{load_path}/skins/#{name}"
-- call the skin's load function if it exists -- call the skin's load function if it exists
if pop.skins[name].load if pop.skins[name].load
pop.skins[name].load pop pop.skins[name].load pop
log "Skin loaded: \"#{name}\"" log "Skin loaded: \"#{name}\""
extensions = filesystem.getDirectoryItems "#{load_path}/extensions" extensions = filesystem.getDirectoryItems "#{load_path}/extensions"
for i = 1, #extensions for i = 1, #extensions
-- ignore non-Lua files -- ignore non-Lua files
unless extensions[i]\sub(-4) == ".lua" unless extensions[i]\sub(-4) == ".lua"
log "Ignored non-Lua file \"#{load_path}/extensions/#{extensions[i]}\"" log "Ignored non-Lua file \"#{load_path}/extensions/#{extensions[i]}\""
continue continue
-- require into pop.extensions by filename -- require into pop.extensions by filename
name = extensions[i]\sub 1, -5 name = extensions[i]\sub 1, -5
log "Requiring \"#{name}\" from \"#{load_path}/extensions/#{name}\"" log "Requiring \"#{name}\" from \"#{load_path}/extensions/#{name}\""
pop.extensions[name] = require "#{load_path}/extensions/#{name}" pop.extensions[name] = require "#{load_path}/extensions/#{name}"
-- call the extension's load function if it exists -- call the extension's load function if it exists
if type(pop.extensions[name]) == "table" and pop.extensions[name].load if type(pop.extensions[name]) == "table" and pop.extensions[name].load
pop.extensions[name].load pop pop.extensions[name].load pop
log "Extension loaded: \"#{name}\"" log "Extension loaded: \"#{name}\""
-- Initialize pop.screen (top element, GUI area) -- Initialize pop.screen (top element, GUI area)
unless pop.screen unless pop.screen
pop.setState(pop.newState()) pop.setState(pop.newState())
pop.newState = (name) -> pop.newState = (name) ->
screen = pop.create("element", false)\setSize(graphics.getWidth!, graphics.getHeight!) screen = pop.create("element", false)\setSize(graphics.getWidth!, graphics.getHeight!)
screen.data.update = true screen.data.update = true
unless name unless name
if pop.states.default if pop.states.default
name = #pop.states + 1 name = #pop.states + 1
else else
name = "default" name = "default"
pop.states[name] = { pop.states[name] = {
screen: screen screen: screen
focused: false focused: false
hovered: false hovered: false
} }
log "Created state: \"#{name}\"" log "Created state: \"#{name}\""
return name return name
pop.setState = (name=default) -> pop.setState = (name=default) ->
if state = pop.states[name] if state = pop.states[name]
pop.state = name pop.state = name
pop.screen = state.screen pop.screen = state.screen
pop.focused = state.focused pop.focused = state.focused
pop.hovered = state.hovered pop.hovered = state.hovered
return true return true
else else
error "Invalid state: \"#{name}\"" error "Invalid state: \"#{name}\""
@ -218,40 +218,40 @@ pop.setState = (name=default) ->
--- @see Element --- @see Element
pop.create = (element, parent=pop.screen, data, ...) -> pop.create = (element, parent=pop.screen, data, ...) ->
-- if valid parent element, use it -- if valid parent element, use it
if inheritsFromElement parent if inheritsFromElement parent
if type(data) == "table" if type(data) == "table"
element = pop.elements[element](parent, data, ...) element = pop.elements[element](parent, data, ...)
else
element = pop.elements[element](parent, {}, data, ...)
insert parent.child, element
insert parent.data.child, element.data
element.parent = parent
element.data.parent = parent.data
-- if explicitly no parent, just create the element
elseif parent == false
if type(data) == "table"
element = pop.elements[element](false, data, ...)
else
element = pop.elements[element](false, {}, data, ...)
element.parent = false
element.data.parent = false
-- else use pop.screen (and "parent" is actually the first argument)
else else
if type(parent) == "table" -- then parent must be data table element = pop.elements[element](parent, {}, data, ...)
element = pop.elements[element](pop.screen, parent, data, ...) insert parent.child, element
else -- parent must be an argument insert parent.data.child, element.data
element = pop.elements[element](pop.screen, {}, parent, data, ...) element.parent = parent
insert pop.screen.child, element element.data.parent = parent.data
insert pop.screen.data.child, element.data -- if explicitly no parent, just create the element
element.parent = pop.screen elseif parent == false
element.data.parent = pop.screen.data if type(data) == "table"
element = pop.elements[element](false, data, ...)
else
element = pop.elements[element](false, {}, data, ...)
element.parent = false
element.data.parent = false
-- else use pop.screen (and "parent" is actually the first argument)
else
if type(parent) == "table" -- then parent must be data table
element = pop.elements[element](pop.screen, parent, data, ...)
else -- parent must be an argument
element = pop.elements[element](pop.screen, {}, parent, data, ...)
insert pop.screen.child, element
insert pop.screen.data.child, element.data
element.parent = pop.screen
element.data.parent = pop.screen.data
if element.parent and element.parent.childAdded if element.parent and element.parent.childAdded
print "working?" print "working?"
element.parent\childAdded element element.parent\childAdded element
return element return element
@ -264,13 +264,13 @@ pop.create = (element, parent=pop.screen, data, ...) ->
--- @see Element --- @see Element
pop.update = (dt, element=pop.screen) -> pop.update = (dt, element=pop.screen) ->
--- @todo Define Elements and @ see that documentation from here. Generic documentation, not specifically element! --- @todo Define Elements and @ see that documentation from here. Generic documentation, not specifically element!
-- data.update boolean controls an element and its children being updated -- data.update boolean controls an element and its children being updated
if element.data.update if element.data.update
if element.update if element.update
element\update dt element\update dt
for i = 1, #element.child for i = 1, #element.child
pop.update dt, element.child[i] pop.update dt, element.child[i]
@ -281,14 +281,14 @@ pop.update = (dt, element=pop.screen) ->
--- @see Element --- @see Element
pop.draw = (element=pop.screen) -> pop.draw = (element=pop.screen) ->
-- data.draw boolean controls an element and its children being drawn -- data.draw boolean controls an element and its children being drawn
if element.data.draw if element.data.draw
local drawChildren local drawChildren
if element.draw if element.draw
drawChildren = element\draw! drawChildren = element\draw!
if drawChildren != false if drawChildren != false
for i = 1, #element.child for i = 1, #element.child
pop.draw element.child[i] pop.draw element.child[i]
@ -301,32 +301,32 @@ pop.draw = (element=pop.screen) ->
--- @treturn boolean Was the event handled? --- @treturn boolean Was the event handled?
pop.mousemoved = (x, y, dx, dy, element=pop.screen) -> pop.mousemoved = (x, y, dx, dy, element=pop.screen) ->
local previously_hovered local previously_hovered
if element == pop.screen if element == pop.screen
previously_hovered = pop.hovered -- we save it because the loop below will change it previously_hovered = pop.hovered -- we save it because the loop below will change it
-- first we find out if we're hovering over anything and set pop.hovered -- first we find out if we're hovering over anything and set pop.hovered
if element.data.draw and element.data.hoverable and (x >= element.data.x) and (x <= element.data.x + element.data.w) and (y >= element.data.y) and (y <= element.data.y + element.data.h) if element.data.draw and element.data.hoverable and (x >= element.data.x) and (x <= element.data.x + element.data.w) and (y >= element.data.y) and (y <= element.data.y + element.data.h)
-- okay, we're over this element for sure, but let's check its children -- okay, we're over this element for sure, but let's check its children
pop.hovered = element pop.hovered = element
-- check in reverse order, it will set pop.hovered to any that match -- check in reverse order, it will set pop.hovered to any that match
for i = 1, #element.child for i = 1, #element.child
pop.mousemoved x, y, dx, dy, element.child[i] pop.mousemoved x, y, dx, dy, element.child[i]
-- check element == pop.screen so this is only called once at the end -- check element == pop.screen so this is only called once at the end
if element == pop.screen if element == pop.screen
-- if we're hovering over something different, log it, and call handlers if relevant -- if we're hovering over something different, log it, and call handlers if relevant
if pop.hovered != previously_hovered if pop.hovered != previously_hovered
log " pop.hovered: #{pop.hovered} (#{pop.hovered.data.type})" log " pop.hovered: #{pop.hovered} (#{pop.hovered.data.type})"
if previously_hovered and previously_hovered.hovered -- previously_hovered can be a false boolean if previously_hovered and previously_hovered.hovered -- previously_hovered can be a false boolean
previously_hovered\hovered false previously_hovered\hovered false
if pop.hovered.hovered if pop.hovered.hovered
pop.hovered\hovered true pop.hovered\hovered true
if pop.focused and pop.focused.mousemoved if pop.focused and pop.focused.mousemoved
return pop.focused\mousemoved x - pop.focused.data.x, y - pop.focused.data.y, dx, dy return pop.focused\mousemoved x - pop.focused.data.x, y - pop.focused.data.y, dx, dy
return false return false
@ -342,41 +342,41 @@ pop.mousemoved = (x, y, dx, dy, element=pop.screen) ->
--- @see Element --- @see Element
pop.mousepressed = (x, y, button, element) -> pop.mousepressed = (x, y, button, element) ->
-- start at the screen, print that we received an event -- start at the screen, print that we received an event
unless element unless element
-- take pre 0.10.0 wheel movement and pass it along -- take pre 0.10.0 wheel movement and pass it along
if button == pop.constants.mouse_wheel_down if button == pop.constants.mouse_wheel_down
pop.wheelmoved 0, -1 pop.wheelmoved 0, -1
return true return true
elseif button == pop.constants.mouse_wheel_up elseif button == pop.constants.mouse_wheel_up
pop.wheelmoved 0, 1 pop.wheelmoved 0, 1
return true return true
log "mousepressed", x, y, button log "mousepressed", x, y, button
element = pop.screen element = pop.screen
-- have we handled the event? -- have we handled the event?
handled = false handled = false
-- if it is inside the current element.. -- if it is inside the current element..
if element.data.draw and (x >= element.data.x) and (x <= element.data.x + element.data.w) and (y >= element.data.y) and (y <= element.data.y + element.data.h) if element.data.draw and (x >= element.data.x) and (x <= element.data.x + element.data.w) and (y >= element.data.y) and (y <= element.data.y + element.data.h)
-- check its child elements in reverse order, returning if something handles it -- check its child elements in reverse order, returning if something handles it
for i = #element.child, 1, -1 for i = #element.child, 1, -1
handled = pop.mousepressed x, y, button, element.child[i] handled = pop.mousepressed x, y, button, element.child[i]
if handled != false if handled != false
return handled return handled
-- if a child hasn't handled it yet, try to handle it, and set pop.focused -- if a child hasn't handled it yet, try to handle it, and set pop.focused
if element.mousepressed if element.mousepressed
handled = element\mousepressed x - element.data.x, y - element.data.y, button handled = element\mousepressed x - element.data.x, y - element.data.y, button
if handled != false if handled != false
log " #{handled} (handled)", "#{element} (#{element.data.type})" log " #{handled} (handled)", "#{element} (#{element.data.type})"
if handled -- you have to explicitly handle a mousepressed event to become focused if handled -- you have to explicitly handle a mousepressed event to become focused
log " ^ focused" log " ^ focused"
pop.focused = element pop.focused = element
-- return whether or not we have handled the event -- return whether or not we have handled the event
return handled return handled
@ -393,63 +393,64 @@ pop.mousepressed = (x, y, button, element) ->
--- @see Element --- @see Element
pop.mousereleased = (x, y, button, element) -> pop.mousereleased = (x, y, button, element) ->
-- we are trying to handle a clicked or mousereleased event -- we are trying to handle a clicked or mousereleased event
clickedHandled = false clickedHandled = false
mousereleasedHandled = false mousereleasedHandled = false
-- if we have an element, and are within its bounds -- if we have an element, and are within its bounds
if element if element
if element.data.draw and (x >= element.data.x) and (x <= element.data.x + element.data.w) and (y >= element.data.y) and (y <= element.data.y + element.data.h) if element.data.draw and (x >= element.data.x) and (x <= element.data.x + element.data.w) and (y >= element.data.y) and (y <= element.data.y + element.data.h)
-- check its children in reverse for handling a clicked or mousereleased event -- check its children in reverse for handling a clicked or mousereleased event
for i = #element.child, 1, -1 for i = #element.child, 1, -1
clickedHandled, mousereleasedHandled = pop.mousereleased x, y, button, element.child[i] clickedHandled, mousereleasedHandled = pop.mousereleased x, y, button, element.child[i]
if clickedHandled != false or mousereleasedHandled != false if clickedHandled != false or mousereleasedHandled != false
return clickedHandled, mousereleasedHandled return clickedHandled, mousereleasedHandled
-- if that doesn't work, we try to handle it ourselves -- if that doesn't work, we try to handle it ourselves
if element.clicked if element.clicked
clickedHandled = element\clicked x - element.data.x, y - element.data.y, button clickedHandled = element\clicked x - element.data.x, y - element.data.y, button
if element.mousereleased if element.mousereleased
mousereleasedHandled = element\mousereleased x - element.data.x, y - element.data.y, button mousereleasedHandled = element\mousereleased x - element.data.x, y - element.data.y, button
-- if we clicked (AND returned true), we're focused! -- if we clicked (AND returned true), we're focused!
if clickedHandled != false if clickedHandled != false
log " #{clickedHandled} (click handled)", "#{element} (#{element.data.type})" log " #{clickedHandled} (click handled)", "#{element} (#{element.data.type})"
if clickedHandled if clickedHandled
log " ^ focused" log " ^ focused"
pop.focused = element pop.focused = element
--- @todo Figure out how to bring a focused element to the front of view (aka the first element in its parent's children). --- @todo Figure out how to bring a focused element to the front of view (aka the first element in its parent's children).
--- (If I do it right here, the for loop above may break! I need to test/figure this out.) --- (If I do it right here, the for loop above may break! I need to test/figure this out.)
--NOTE this might cause an error in the above for loop! --NOTE this might cause an error in the above for loop!
-- basically, move focused element to front of its parent's child -- basically, move focused element to front of its parent's child
--element.parent\focusChild element --element.parent\focusChild element
--table.insert element.parent, element.parent\removeChild(element), --table.insert element.parent, element.parent\removeChild(element),
if mousereleasedHandled != false if mousereleasedHandled != false
log " #{mousereleasedHandled} (release handled)", "#{element} (#{element.data.type})" log " #{mousereleasedHandled} (release handled)", "#{element} (#{element.data.type})"
-- else, check for focused element, and then default to pop.screen to begin! (and print that we received an event) -- else, check for focused element, and then default to pop.screen to begin! (and print that we received an event)
else else
log "mousereleased", x, y, button log "mousereleased", x, y, button
if element = pop.focused if element = pop.focused
if element.data.draw and (x >= element.data.x) and (x <= element.data.x + element.data.w) and (y >= element.data.y) and (y <= element.data.y + element.data.h) if element.data.draw and (x >= element.data.x) and (x <= element.data.x + element.data.w) and (y >= element.data.y) and (y <= element.data.y + element.data.h)
if element.clicked if element.clicked
clickedHandled = element\clicked x - element.data.x, y - element.data.y, button clickedHandled = element\clicked x - element.data.x, y - element.data.y, button
if clickedHandled != false if clickedHandled != false
log " #{clickedHandled} (click handled)", "#{element} (#{element.data.type})" log " #{clickedHandled} (click handled)", "#{element} (#{element.data.type})"
-- a focused element needs to know when it has been released no matter what!
if element.mousereleased
mousereleasedHandled = element\mousereleased x - element.data.x, y - element.data.y, button
if mousereleasedHandled != false
log " #{mousereleasedHandled} (release handled)", "#{element} (#{element.data.type})"
if clickedHandled != false or mousereleasedHandled != false
return clickedHandled, mousereleasedHandled
pop.mousereleased x, y, button, pop.screen -- a focused element needs to know when it has been released no matter what!
if element.mousereleased
mousereleasedHandled = element\mousereleased x - element.data.x, y - element.data.y, button
if mousereleasedHandled != false
log " #{mousereleasedHandled} (release handled)", "#{element} (#{element.data.type})"
if clickedHandled != false or mousereleasedHandled != false
return clickedHandled, mousereleasedHandled
--print "#{clickedHandled}, #{mousereleasedHandled}, #{element}" pop.mousereleased x, y, button, pop.screen
return clickedHandled, mousereleasedHandled -- print "#{clickedHandled}, #{mousereleasedHandled}, #{element}"
return clickedHandled, mousereleasedHandled
@ -459,12 +460,12 @@ pop.mousereleased = (x, y, button, element) ->
--- @tparam number y The distance the wheel moved on the y-axis. --- @tparam number y The distance the wheel moved on the y-axis.
--- @treturn boolean Was the event handled? --- @treturn boolean Was the event handled?
pop.wheelmoved = (x, y) -> pop.wheelmoved = (x, y) ->
log "wheelmoved", x, y log "wheelmoved", x, y
if pop.hovered and pop.hovered.wheelmoved if pop.hovered and pop.hovered.wheelmoved
return pop.hovered\wheelmoved x, y return pop.hovered\wheelmoved x, y
return false return false
@ -474,14 +475,14 @@ pop.wheelmoved = (x, y) ->
--- @treturn boolean Was the event handled? --- @treturn boolean Was the event handled?
pop.keypressed = (key) -> pop.keypressed = (key) ->
log "keypressed", key log "keypressed", key
-- keypressed events must be on visible elements -- keypressed events must be on visible elements
element = pop.focused element = pop.focused
if element and element.keypressed and element.data.draw if element and element.keypressed and element.data.draw
return element.keypressed key return element.keypressed key
return false return false
@ -491,14 +492,14 @@ pop.keypressed = (key) ->
--- @treturn boolean Was the event handled? --- @treturn boolean Was the event handled?
pop.keyreleased = (key) -> pop.keyreleased = (key) ->
log "keyreleased", key log "keyreleased", key
-- keyreleased events are always called -- keyreleased events are always called
element = pop.focused element = pop.focused
if element and element.keyreleased if element and element.keyreleased
return element.keyreleased key return element.keyreleased key
return false return false
@ -508,37 +509,37 @@ pop.keyreleased = (key) ->
--- @treturn boolean Was the text input handled? --- @treturn boolean Was the text input handled?
pop.textinput = (text) -> pop.textinput = (text) ->
log "textinput", text log "textinput", text
-- textinput events must be on visible elements -- textinput events must be on visible elements
element = pop.focused element = pop.focused
if element and element.textinput and element.data.draw if element and element.textinput and element.data.draw
return element.textinput text return element.textinput text
return false return false
--- @todo document pop.import --- @todo document pop.import
pop.import = (data, parent=pop.screen) -> pop.import = (data, parent=pop.screen) ->
local element local element
if type(data) == "string" if type(data) == "string"
data = loads(data) data = loads(data)
element = pop.create(data.type, parent, data) element = pop.create(data.type, parent, data)
else else
element = pop.elements[data.type](parent, data) --why is it not the same as the other way? element = pop.elements[data.type](parent, data) --why is it not the same as the other way?
insert parent.child, element insert parent.child, element
for i = 1, #data.child for i = 1, #data.child
pop.import data.child[i], element pop.import data.child[i], element
--- @todo document pop.export --- @todo document pop.export
pop.export = (element=pop.screen) -> pop.export = (element=pop.screen) ->
return dumps(element.data) return dumps(element.data)
@ -549,23 +550,23 @@ pop.export = (element=pop.screen) ->
--- @see Element --- @see Element
pop.debugDraw = (element=pop.screen) -> pop.debugDraw = (element=pop.screen) ->
if element.debugDraw if element.debugDraw
element\debugDraw! element\debugDraw!
graphics.setLineWidth 1 graphics.setLineWidth 1
graphics.setColor 0, 0, 0, 100 graphics.setColor 0, 0, 0, 100
graphics.rectangle "fill", element.data.x, element.data.y, element.data.w, element.data.h graphics.rectangle "fill", element.data.x, element.data.y, element.data.w, element.data.h
graphics.setColor 150, 150, 150, 150 graphics.setColor 150, 150, 150, 150
graphics.rectangle "line", element.data.x, element.data.y, element.data.w, element.data.h graphics.rectangle "line", element.data.x, element.data.y, element.data.w, element.data.h
graphics.setColor 200, 200, 200, 255 graphics.setColor 200, 200, 200, 255
if element.debugInfo if element.debugInfo
graphics.print "#{element.__class.__name\sub 1, 1} (#{element\debugInfo!})", element.data.x, element.data.y graphics.print "#{element.__class.__name\sub 1, 1} (#{element\debugInfo!})", element.data.x, element.data.y
else else
graphics.print "#{element.__class.__name\sub 1, 1}", element.data.x, element.data.y graphics.print "#{element.__class.__name\sub 1, 1}", element.data.x, element.data.y
for i = 1, #element.child for i = 1, #element.child
pop.debugDraw element.child[i] pop.debugDraw element.child[i]
@ -576,32 +577,32 @@ pop.debugDraw = (element=pop.screen) ->
--- @see Element --- @see Element
pop.printElementTree = (element=pop.screen, fn, depth=0) -> pop.printElementTree = (element=pop.screen, fn, depth=0) ->
if "table" != type element if "table" != type element
depth = fn depth = fn
fn = element fn = element
element = pop.screen element = pop.screen
if "number" == type fn if "number" == type fn
depth = fn depth = fn
fn = nil fn = nil
unless depth unless depth
depth=0 depth=0
--- @todo Write debugInfo things for elements. --- @todo Write debugInfo things for elements.
cls = element.__class.__name cls = element.__class.__name
if element.debugInfo if element.debugInfo
cls ..= " (#{element\debugInfo!})" cls ..= " (#{element\debugInfo!})"
if fn if fn
cls ..= " #{fn element}" cls ..= " #{fn element}"
if depth > 0 if depth > 0
log string.rep("-", depth) .. " #{cls}" log string.rep("-", depth) .. " #{cls}"
else else
log cls log cls
for i = 1, #element.child for i = 1, #element.child
pop.printElementTree element.child[i], fn, depth + 1 pop.printElementTree element.child[i], fn, depth + 1

170
main.moon
View File

@ -8,125 +8,125 @@ pop = require ""
debug = false debug = false
love.load = -> love.load = ->
test_original = -> test_original = ->
pop.text("Hello World!")\align "center", "center" pop.text("Hello World!")\align "center", "center"
testWindow = pop.window({windowBackground: {200, 200, 200}, closeable: true, maximizeable: true, minimizeable: true}, "Testing Window")\move(20, 20)\setSize(200, 100)\align "right", "top" testWindow = pop.window({windowBackground: {200, 200, 200}, closeable: true, maximizeable: true, minimizeable: true}, "Testing Window")\move(20, 20)\setSize(200, 100)\align "right", "top"
print testWindow.window_area print testWindow.window_area
pop.window({maximizeable: true}, "Test Window #2")\align "center", "bottom" pop.window({maximizeable: true}, "Test Window #2")\align "center", "bottom"
pop.window({moveable: false}, "Immoveable!") pop.window({moveable: false}, "Immoveable!")
centerBox = pop.box({w: 200, h: 200}, {255, 255, 0, 120})\align "center", "center" centerBox = pop.box({w: 200, h: 200}, {255, 255, 0, 120})\align "center", "center"
pop.box(centerBox, {w: 10, h: 20})\align "left", "top" pop.box(centerBox, {w: 10, h: 20})\align "left", "top"
pop.box(centerBox, {w: 30, h: 30})\align "center", "top" pop.box(centerBox, {w: 30, h: 30})\align "center", "top"
pop.box(centerBox, {w: 5, h: 40})\align "left", "center" pop.box(centerBox, {w: 5, h: 40})\align "left", "center"
pop.box(centerBox, {w: 50, h: 50})\align "right", "center" pop.box(centerBox, {w: 50, h: 50})\align "right", "center"
pop.box(centerBox)\align("left", "bottom")\setSize 5, 5 pop.box(centerBox)\align("left", "bottom")\setSize 5, 5
pop.box(centerBox, {w: 25, h: 10})\align "center", "bottom" pop.box(centerBox, {w: 25, h: 10})\align "center", "bottom"
pop.text(centerBox, "Align me!")\align "right", "top" pop.text(centerBox, "Align me!")\align "right", "top"
pop.window(centerBox, {closeable: true})\align "right", "bottom" pop.window(centerBox, {closeable: true})\align "right", "bottom"
centerBox\setPadding 5 centerBox\setPadding 5
pop.box(centerBox, {w: 10, h: 20, background: {0, 0, 255, 100}})\align "left", "top" pop.box(centerBox, {w: 10, h: 20, background: {0, 0, 255, 100}})\align "left", "top"
pop.box(centerBox, {w: 30, h: 30, background: {0, 0, 255, 100}})\align "center", "top" pop.box(centerBox, {w: 30, h: 30, background: {0, 0, 255, 100}})\align "center", "top"
pop.box(centerBox, {w: 5, h: 40, background: {0, 0, 255, 100}})\align "left", "center" pop.box(centerBox, {w: 5, h: 40, background: {0, 0, 255, 100}})\align "left", "center"
pop.box(centerBox, {w: 50, h: 50, background: {0, 0, 255, 100}})\align "right", "center" pop.box(centerBox, {w: 50, h: 50, background: {0, 0, 255, 100}})\align "right", "center"
pop.text(centerBox, {color: {0, 0, 255, 100}}, "Text!")\align("left", "bottom")--\setSize 5, 5 pop.text(centerBox, {color: {0, 0, 255, 100}}, "Text!")\align("left", "bottom")--\setSize 5, 5
pop.box(centerBox, {w: 25, h: 10, background: {0, 0, 255, 100}})\align "center", "bottom" pop.box(centerBox, {w: 25, h: 10, background: {0, 0, 255, 100}})\align "center", "bottom"
pop.text(centerBox, {color: {0, 0, 255, 100}}, "Align me!")\align "right", "top" pop.text(centerBox, {color: {0, 0, 255, 100}}, "Align me!")\align "right", "top"
pop.window(centerBox, {titleColor: {0, 0, 0, 150}, titleBackground: {0, 0, 255, 100}, windowBackground: {200, 200, 255, 100}})\align "right", "bottom" pop.window(centerBox, {titleColor: {0, 0, 0, 150}, titleBackground: {0, 0, 255, 100}, windowBackground: {200, 200, 255, 100}})\align "right", "bottom"
pop.window(centerBox, {containMethod: "title", w: 125}, "Title can't leave") pop.window(centerBox, {containMethod: "title", w: 125}, "Title can't leave")
pop.window(centerBox, {containMethod: "body", w: 125}, "Body can't leave") pop.window(centerBox, {containMethod: "body", w: 125}, "Body can't leave")
test_original_color_clipRegion = -> test_original_color_clipRegion = ->
testWindow = pop.window({windowBackground: {200, 200, 200}, closeable: true, maximizeable: true, minimizeable: true}, "Testing Window")\move(20, 20)\setSize(200, 100)\align "right", "top" testWindow = pop.window({windowBackground: {200, 200, 200}, closeable: true, maximizeable: true, minimizeable: true}, "Testing Window")\move(20, 20)\setSize(200, 100)\align "right", "top"
print testWindow.window_area print testWindow.window_area
pop.window({maximizeable: true}, "Test Window #2")\align "center", "bottom" pop.window({maximizeable: true}, "Test Window #2")\align "center", "bottom"
pop.window({moveable: false}, "Immoveable!") pop.window({moveable: false}, "Immoveable!")
-- alignment testing -- alignment testing
-- centerBox = pop.clipRegion {w: 200, h: 200, verticalAlign: "center", horizontalAlign: "center"} -- centerBox = pop.clipRegion {w: 200, h: 200, verticalAlign: "center", horizontalAlign: "center"}
-- centerBox = pop.box({w: 200, h: 200}, {255, 255, 0, 120})\align "center", "center" -- centerBox = pop.box({w: 200, h: 200}, {255, 255, 0, 120})\align "center", "center"
centerBox = pop.box({w: 200, h: 200}, {0, 0, 0, 255})\align "center", "center" centerBox = pop.box({w: 200, h: 200}, {0, 0, 0, 255})\align "center", "center"
pop.box(centerBox, {w: 10, h: 20})\align "left", "top" pop.box(centerBox, {w: 10, h: 20})\align "left", "top"
pop.box(centerBox, {w: 30, h: 30})\align "center", "top" pop.box(centerBox, {w: 30, h: 30})\align "center", "top"
pop.box(centerBox, {w: 5, h: 40})\align "left", "center" pop.box(centerBox, {w: 5, h: 40})\align "left", "center"
pop.box(centerBox, {w: 50, h: 50})\align "right", "center" pop.box(centerBox, {w: 50, h: 50})\align "right", "center"
pop.box(centerBox)\align("left", "bottom")\setSize 5, 5 pop.box(centerBox)\align("left", "bottom")\setSize 5, 5
pop.box(centerBox, {w: 25, h: 10})\align "center", "bottom" pop.box(centerBox, {w: 25, h: 10})\align "center", "bottom"
pop.text(centerBox, "Align me!")\align "right", "top" pop.text(centerBox, "Align me!")\align "right", "top"
pop.window(centerBox, {closeable: true, w: 80, h: 63})\align "right", "bottom" pop.window(centerBox, {closeable: true, w: 80, h: 63})\align "right", "bottom"
pop.window(centerBox, {titleColor: {0, 0, 0, 150}, titleBackground: {0, 0, 255, 255}, windowBackground: {200, 200, 255, 100}, w: 60, h: 50})\align "center", "bottom" pop.window(centerBox, {titleColor: {0, 0, 0, 150}, titleBackground: {0, 0, 255, 255}, windowBackground: {200, 200, 255, 100}, w: 60, h: 50})\align "center", "bottom"
centerBox\setPadding 5 centerBox\setPadding 5
pop.box(centerBox, {w: 10, h: 20, background: {0, 0, 255, 255}})\align "left", "top" pop.box(centerBox, {w: 10, h: 20, background: {0, 0, 255, 255}})\align "left", "top"
pop.box(centerBox, {w: 30, h: 30, background: {0, 255, 0, 255}})\align "center", "top" pop.box(centerBox, {w: 30, h: 30, background: {0, 255, 0, 255}})\align "center", "top"
pop.box(centerBox, {w: 5, h: 40, background: {255, 0, 0, 255}})\align "left", "center" pop.box(centerBox, {w: 5, h: 40, background: {255, 0, 0, 255}})\align "left", "center"
pop.box(centerBox, {w: 50, h: 50, background: {0, 255, 255, 255}})\align "right", "center" pop.box(centerBox, {w: 50, h: 50, background: {0, 255, 255, 255}})\align "right", "center"
pop.text(centerBox, {color: {255, 0, 255, 255}}, "Text!")\align("left", "bottom")--\setSize 5, 5 pop.text(centerBox, {color: {255, 0, 255, 255}}, "Text!")\align("left", "bottom")--\setSize 5, 5
pop.box(centerBox, {w: 25, h: 10, background: {100, 100, 255, 255}})\align "center", "bottom" pop.box(centerBox, {w: 25, h: 10, background: {100, 100, 255, 255}})\align "center", "bottom"
pop.text(centerBox, {color: {255, 255, 0, 255}}, "Align me!")\align "right", "top" pop.text(centerBox, {color: {255, 255, 0, 255}}, "Align me!")\align "right", "top"
-- pop.window(centerBox, {containMethod: "title", w: 125}, "Title can't leave") -- pop.window(centerBox, {containMethod: "title", w: 125}, "Title can't leave")
pop.window(centerBox, {containMethod: "body", w: 125, h: 30, margin: 30}, "Body can't leave") pop.window(centerBox, {containMethod: "body", w: 125, h: 30, margin: 30}, "Body can't leave")
test_obession = -> test_obession = ->
partsGrid = pop.dynamicGrid! partsGrid = pop.dynamicGrid!
pop.window({w: graphics.getWidth!/2, h: graphics.getHeight!, titleBar: false})\add({ pop.window({w: graphics.getWidth!/2, h: graphics.getHeight!, titleBar: false})\add({
pop.box({h: 17}) -- temporary height pop.box({h: 17}) -- temporary height
pop.scrollbox()\add( pop.scrollbox()\add(
partsGrid partsGrid
) )
pop.grid()\add({ pop.grid()\add({
pop.button() pop.button()
pop.button() pop.button()
pop.button() pop.button()
}) })
}) })
-- test_original! -- test_original!
test_original_color_clipRegion! test_original_color_clipRegion!
-- test_obession! -- test_obession!
love.update = (dt) -> love.update = (dt) ->
pop.update dt pop.update dt
love.draw = -> love.draw = ->
pop.draw! pop.draw!
pop.debugDraw! if debug pop.debugDraw! if debug
love.mousemoved = (x, y, dx, dy) -> love.mousemoved = (x, y, dx, dy) ->
pop.mousemoved x, y, dx, dy pop.mousemoved x, y, dx, dy
love.mousepressed = (x, y, button) -> love.mousepressed = (x, y, button) ->
pop.mousepressed x, y, button pop.mousepressed x, y, button
love.mousereleased = (x, y, button) -> love.mousereleased = (x, y, button) ->
pop.mousereleased x, y, button pop.mousereleased x, y, button
love.wheelmoved = (x, y) -> love.wheelmoved = (x, y) ->
pop.wheelmoved x, y pop.wheelmoved x, y
love.keypressed = (key) -> love.keypressed = (key) ->
if key == "escape" if key == "escape"
love.event.quit! love.event.quit!
elseif key == "d" elseif key == "d"
debug = not debug debug = not debug
elseif key == "t" elseif key == "t"
print("pop.focused", pop.focused) print("pop.focused", pop.focused)
love.keyreleased = (key) -> love.keyreleased = (key) ->
pop.keyreleased key pop.keyreleased key
love.textinput = (text) -> love.textinput = (text) ->
pop.textinput text pop.textinput text

View File

@ -1,22 +1,22 @@
lfs = require "lfs" lfs = require "lfs"
return { return {
getVersion: -> getVersion: ->
0, 10, 1, "Super Toast" 0, 10, 1, "Super Toast"
filesystem: filesystem:
getDirectoryItems: (path) -> getDirectoryItems: (path) ->
ok, results = pcall -> ok, results = pcall ->
results = {} results = {}
for file in lfs.dir lfs.currentdir! .. "/" .. path for file in lfs.dir lfs.currentdir! .. "/" .. path
table.insert results, file table.insert results, file
return results return results
if ok if ok
return results return results
else else
return {} return {}
graphics: graphics:
getWidth: -> getWidth: ->
return 1280 return 1280
getHeight: -> getHeight: ->
return 720 return 720
} }

View File

@ -2,77 +2,77 @@ lfs = require "lfs"
expose "fake LOVE 0.10.1", -> expose "fake LOVE 0.10.1", ->
_G.love = require "spec/love" _G.love = require "spec/love"
describe "Pop.Box", -> describe "Pop.Box", ->
--it "errors when require'd wrong", -> --it "errors when require'd wrong", ->
-- assert.error -> require "init" -- assert.error -> require "init"
it "can be required by 'init'", -> it "can be required by 'init'", ->
assert.has_no.errors -> require "init" assert.has_no.errors -> require "init"
pending "errors if you use LOVE < 0.9.1", -> pending "errors if you use LOVE < 0.9.1", ->
describe "pop.load", -> describe "pop.load", ->
pending "loads all elements", -> pending "loads all elements", ->
-- check they are in elements[name] -- check they are in elements[name]
-- check specifics if able have used their load functions -- check specifics if able have used their load functions
-- if able, check that custom wraps have been called -- if able, check that custom wraps have been called
pending "loads all skins", -> pending "loads all skins", ->
-- see checks for loading all elements -- see checks for loading all elements
pending "loads all extensions", -> pending "loads all extensions", ->
-- see checks for loading all elements -- see checks for loading all elements
it "creates an element the size of the game window", -> it "creates an element the size of the game window", ->
pop = require "init" pop = require "init"
w, h = pop.screen\getSize! w, h = pop.screen\getSize!
assert.are.equal love.graphics.getWidth!, w assert.are.equal love.graphics.getWidth!, w
assert.are.equal love.graphics.getHeight!, h assert.are.equal love.graphics.getHeight!, h
pending "check inherit checker", -> pending "check inherit checker", ->
describe "pop.create", -> describe "pop.create", ->
-- these need to check parent/child relations and data relations -- these need to check parent/child relations and data relations
pending "creates elements with pop.screen by default", -> pending "creates elements with pop.screen by default", ->
pending "creates elements with no parent when you pass false", -> pending "creates elements with no parent when you pass false", ->
pending "creates elements with specified parent when passed an element", -> pending "creates elements with specified parent when passed an element", ->
describe "pop.update", -> describe "pop.update", ->
pending "only updates when data.update is truthy", -> pending "only updates when data.update is truthy", ->
pending "updates all children", -> pending "updates all children", ->
describe "pop.draw", -> describe "pop.draw", ->
pending "draws elements only when data.draw is truthy", -> pending "draws elements only when data.draw is truthy", ->
pending "draws all children", -> pending "draws all children", ->
describe "pop.mousemoved", -> describe "pop.mousemoved", ->
pending "handles mousemoved events on a focused element", -> pending "handles mousemoved events on a focused element", ->
--idk exactly how to make a unit test for this... --idk exactly how to make a unit test for this...
describe "pop.mousepressed", -> describe "pop.mousepressed", ->
pending "idk", -> pending "idk", ->
describe "pop.mousereleased", -> describe "pop.mousereleased", ->
describe "click handling", -> describe "click handling", ->
describe "mouserelease handling", -> describe "mouserelease handling", ->
describe "pop.keypressed", -> describe "pop.keypressed", ->
pending "idk", -> pending "idk", ->
describe "pop.keyreleased", -> describe "pop.keyreleased", ->
pending "idk", -> pending "idk", ->
describe "pop.textinput", -> describe "pop.textinput", ->
pending "idk", -> pending "idk", ->
describe "pop.debugDraw", -> describe "pop.debugDraw", ->
pending "idk", -> pending "idk", ->
describe "pop.printElementTree", -> describe "pop.printElementTree", ->
pending "idk", -> pending "idk", ->

View File

@ -12,19 +12,19 @@
--- @see Element --- @see Element
inheritsFromElement = (object) -> inheritsFromElement = (object) ->
if object and type(object) == "table" and object.__class if object and type(object) == "table" and object.__class
cls = object.__class cls = object.__class
if cls.__name == "element" if cls.__name == "element"
return true return true
while cls.__parent while cls.__parent
cls = cls.__parent cls = cls.__parent
if cls.__name == "element" if cls.__name == "element"
return true return true
return false return false
return { return {
:inheritsFromElement :inheritsFromElement
} }