2016-08-21 05:29:16 +00:00
|
|
|
--- A generic element every element must inherit from.
|
2016-08-21 07:49:16 +00:00
|
|
|
--- @classmod element
|
2016-08-21 05:29:16 +00:00
|
|
|
--- @copyright Paul Liverman III (2016)
|
|
|
|
--- @license The MIT License (MIT)
|
|
|
|
|
2016-10-31 05:19:24 +00:00
|
|
|
import graphics from love
|
2017-05-01 01:01:19 +00:00
|
|
|
import floor, max from math
|
2017-08-13 10:52:45 +00:00
|
|
|
import inheritsFromElement from require "#{(...)\sub 1, -19}/util"
|
2016-10-31 05:19:24 +00:00
|
|
|
|
2016-08-21 05:29:16 +00:00
|
|
|
class element
|
2016-08-23 01:19:58 +00:00
|
|
|
--- Constructor expects nothing, or a data table describing it.
|
2016-09-08 04:42:19 +00:00
|
|
|
--- @tparam ?Element|false parent The parent element.
|
|
|
|
--- @tparam table data[opt] The data (state) for this element.
|
|
|
|
--- @treturn element self
|
2016-08-23 01:19:58 +00:00
|
|
|
new: (@parent, @data={}) =>
|
2016-11-25 03:37:53 +00:00
|
|
|
if type(@data) != "table"
|
2016-09-08 03:53:22 +00:00
|
|
|
@data = {}
|
2016-08-21 05:29:16 +00:00
|
|
|
|
2016-10-31 05:19:24 +00:00
|
|
|
@data.parent = false unless @data.parent
|
2016-09-08 04:42:19 +00:00
|
|
|
@data.child = {} unless @data.child
|
2017-04-30 20:10:03 +00:00
|
|
|
@data.type = "element" unless @data.type
|
|
|
|
|
2017-04-30 21:13:56 +00:00
|
|
|
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
|
2016-09-08 04:42:19 +00:00
|
|
|
@data.w = 0 unless @data.w
|
|
|
|
@data.h = 0 unless @data.h
|
2017-04-30 20:10:03 +00:00
|
|
|
|
2017-04-09 09:02:14 +00:00
|
|
|
@data.update = true if @data.update == nil
|
2016-09-08 04:42:19 +00:00
|
|
|
@data.draw = true if @data.draw == nil
|
2017-04-12 10:37:29 +00:00
|
|
|
@data.hoverable = true if @data.hoverable == nil
|
2017-04-30 21:13:56 +00:00
|
|
|
--@data.static = false if @data.static == nil
|
2017-04-30 20:10:03 +00:00
|
|
|
|
2016-11-25 03:37:53 +00:00
|
|
|
@data.align = true if (@data.align == nil) and @parent
|
|
|
|
@data.vertical = "top" unless @data.vertical
|
|
|
|
@data.horizontal = "left" unless @data.horizontal
|
2017-05-01 01:01:19 +00:00
|
|
|
|
|
|
|
@data.margin = 0 unless @data.margin
|
|
|
|
@data.horizontalMargin = 0 unless @data.horizontalMargin
|
|
|
|
@data.verticalMargin = 0 unless @data.verticalMargin
|
|
|
|
|
2017-04-30 21:13:56 +00:00
|
|
|
@data.padding = 0 unless @data.padding
|
2017-05-01 01:01:19 +00:00
|
|
|
@data.horizontalPadding = 0 unless @data.horizontalPadding
|
|
|
|
@data.verticalPadding = 0 unless @data.verticalPadding
|
2016-09-08 04:42:19 +00:00
|
|
|
|
2016-10-31 05:19:24 +00:00
|
|
|
@child = {}
|
|
|
|
|
2016-11-25 03:37:53 +00:00
|
|
|
--- @todo doc me
|
|
|
|
align: (horizontal, vertical, toPixel=true) =>
|
2017-04-09 00:10:44 +00:00
|
|
|
unless @data.align return @
|
2016-11-25 03:37:53 +00:00
|
|
|
|
|
|
|
@data.horizontal = horizontal if horizontal
|
|
|
|
@data.vertical = vertical if vertical
|
|
|
|
|
|
|
|
@data.x = @parent.data.x
|
|
|
|
@data.y = @parent.data.y
|
|
|
|
|
|
|
|
switch @data.horizontal
|
2017-04-30 21:13:56 +00:00
|
|
|
when "left"
|
2017-05-01 01:01:19 +00:00
|
|
|
@data.x += max(@parent.data.padding + @parent.data.horizontalPadding, @data.margin + @data.horizontalMargin)
|
2016-11-25 03:37:53 +00:00
|
|
|
when "center"
|
|
|
|
@data.x += (@parent.data.w - @data.w) / 2
|
|
|
|
when "right"
|
2017-05-01 01:01:19 +00:00
|
|
|
@data.x += @parent.data.w - @data.w - max(@parent.data.padding + @parent.data.horizontalPadding, @data.margin + @data.horizontalMargin)
|
2016-11-25 03:37:53 +00:00
|
|
|
|
|
|
|
switch @data.vertical
|
2017-04-30 21:13:56 +00:00
|
|
|
when "top"
|
2017-05-01 01:01:19 +00:00
|
|
|
@data.y += @parent.data.padding + @data.margin + @data.verticalMargin
|
2016-11-25 03:37:53 +00:00
|
|
|
when "center"
|
|
|
|
@data.y += (@parent.data.h - @data.h) / 2
|
2016-11-25 05:32:04 +00:00
|
|
|
when "bottom"
|
2017-05-01 01:01:19 +00:00
|
|
|
@data.y += @parent.data.h - @data.h - max(@parent.data.padding + @parent.data.verticalPadding, @data.margin + @data.verticalMargin)
|
2016-11-25 03:37:53 +00:00
|
|
|
|
|
|
|
if toPixel
|
|
|
|
@data.x = floor @data.x
|
|
|
|
@data.y = floor @data.y
|
|
|
|
|
|
|
|
return @
|
|
|
|
|
2017-04-09 09:02:14 +00:00
|
|
|
--- @todo document this
|
|
|
|
setPosition: (x, y, toPixel=true) =>
|
2017-04-11 03:32:31 +00:00
|
|
|
dx, dy = @data.x, @data.y
|
|
|
|
|
2017-04-09 09:02:14 +00:00
|
|
|
if x
|
|
|
|
@data.x = x
|
2017-04-30 21:13:56 +00:00
|
|
|
switch @data.horizontal
|
|
|
|
when "center"
|
|
|
|
@data.x -= @data.w / 2
|
|
|
|
when "right"
|
|
|
|
@data.x -= @data.w
|
|
|
|
|
2017-04-09 09:02:14 +00:00
|
|
|
if y
|
|
|
|
@data.y = y
|
2017-04-30 21:13:56 +00:00
|
|
|
switch @data.vertical
|
|
|
|
when "center"
|
|
|
|
@data.y -= @data.h / 2
|
|
|
|
when "bottom"
|
|
|
|
@data.y -= @data.h
|
2017-04-09 09:02:14 +00:00
|
|
|
|
|
|
|
if toPixel
|
|
|
|
@data.x = floor @data.x
|
|
|
|
@data.y = floor @data.y
|
|
|
|
|
2017-04-11 03:32:31 +00:00
|
|
|
-- new minus old is difference that children need to be moved
|
|
|
|
dx = @data.x - dx
|
|
|
|
dy = @data.y - dy
|
|
|
|
for child in *@child
|
2017-04-13 15:11:45 +00:00
|
|
|
child\move dx, dy
|
2017-04-11 03:32:31 +00:00
|
|
|
|
2017-04-09 09:02:14 +00:00
|
|
|
return @
|
|
|
|
|
2017-04-13 21:28:52 +00:00
|
|
|
--- @todo doc me
|
|
|
|
getPosition: =>
|
2017-04-30 21:13:56 +00:00
|
|
|
x, y = @data.x, @data.y
|
|
|
|
|
|
|
|
switch @data.horizontal
|
|
|
|
when "center"
|
|
|
|
x += @data.w / 2
|
|
|
|
when "right"
|
|
|
|
y += @data.w
|
|
|
|
|
|
|
|
switch @data.vertical
|
|
|
|
when "center"
|
|
|
|
y += @data.h / 2
|
|
|
|
when "bottom"
|
|
|
|
y += @data.h
|
|
|
|
|
|
|
|
return x, y
|
2017-04-13 21:28:52 +00:00
|
|
|
|
2017-01-10 20:57:02 +00:00
|
|
|
--- Sets an element's width/height. Fixes alignment if needed.
|
2016-09-08 04:42:19 +00:00
|
|
|
--- @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
|
|
|
|
|
2017-01-10 20:57:02 +00:00
|
|
|
@align!
|
|
|
|
|
2016-09-08 04:42:19 +00:00
|
|
|
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
|
2017-04-30 21:13:56 +00:00
|
|
|
@align!
|
2016-09-08 04:42:19 +00:00
|
|
|
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
|
2017-04-30 21:13:56 +00:00
|
|
|
@align!
|
2016-09-08 04:42:19 +00:00
|
|
|
return @
|
|
|
|
|
|
|
|
--- Returns an element's height.
|
|
|
|
--- @treturn integer Height.
|
|
|
|
getHeight: =>
|
|
|
|
return @data.h
|
2017-04-08 20:44:31 +00:00
|
|
|
|
2017-04-30 21:13:56 +00:00
|
|
|
--- @todo doc me
|
|
|
|
adjustSize: (w, h) =>
|
|
|
|
W, H = @getSize!
|
|
|
|
|
|
|
|
if w
|
|
|
|
W += w
|
|
|
|
if h
|
|
|
|
H += h
|
|
|
|
|
|
|
|
@setSize W, H
|
|
|
|
|
|
|
|
return @
|
|
|
|
|
2017-04-08 20:44:31 +00:00
|
|
|
--- Moves an element by specified x/y.
|
|
|
|
--- @treturn element self
|
|
|
|
move: (x=0, y=0) =>
|
2017-04-30 21:13:56 +00:00
|
|
|
--if @data.static return @
|
2017-04-11 03:32:31 +00:00
|
|
|
|
2017-04-08 20:44:31 +00:00
|
|
|
@data.x += x
|
|
|
|
@data.y += y
|
2017-04-30 21:13:56 +00:00
|
|
|
|
|
|
|
for child in *@child
|
|
|
|
child\move x, y
|
|
|
|
|
2017-04-08 20:44:31 +00:00
|
|
|
return @
|
2017-04-09 09:02:14 +00:00
|
|
|
|
2017-04-30 21:13:56 +00:00
|
|
|
setPadding: (padding) =>
|
|
|
|
@data.padding = padding
|
|
|
|
@align!
|
|
|
|
return @
|
|
|
|
|
|
|
|
getPadding: =>
|
|
|
|
return @data.padding
|
|
|
|
|
2017-04-30 23:40:29 +00:00
|
|
|
indexOf: (element) =>
|
|
|
|
for i = 1, #@child
|
|
|
|
if @child[i] == element
|
|
|
|
return i
|
|
|
|
|
2017-05-01 02:24:47 +00:00
|
|
|
dataIndexOf: (data) =>
|
|
|
|
for i = 1, #@data.child
|
|
|
|
if @data.child[i] == data
|
|
|
|
return i
|
|
|
|
|
2017-05-11 21:47:33 +00:00
|
|
|
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 @
|
|
|
|
|
2017-04-09 09:02:14 +00:00
|
|
|
--- Deletes references to this element and then deletes it.
|
|
|
|
delete: =>
|
2017-04-13 15:11:45 +00:00
|
|
|
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
|