diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..ff9a3bf --- /dev/null +++ b/build.bat @@ -0,0 +1,5 @@ +@ECHO OFF +cd src +"%cd%\..\moonc.exe" -t ../lib . +cd .. +xcopy /S /Y "%cd%\lib\pop\*" "%cd%\demo\pop\*" diff --git a/demo/main.lua b/demo/main.lua index 926071e..0ec2ba5 100644 --- a/demo/main.lua +++ b/demo/main.lua @@ -1,4 +1,4 @@ -local pop = require "pop" +local pop = require("pop")() local lg = love.graphics @@ -7,35 +7,35 @@ local testsRun = false local debugDrawEnabled = false function love.load() - pop.text(nil, "Press \"s\" to show objects for visual testing/demo.\nPress \"t\" to run tests.\nPress \"d\" to toggle debug draw."):move(2, 2) + pop:text(nil, "Press \"s\" to show objects for visual testing/demo.\nPress \"t\" to run tests.\nPress \"d\" to toggle debug draw."):move(2, 2) --TODO correct the fact that the size is wrong here! (height doesn't take into account \n) --NOTE width? Is width calculated correctly when \n's exist? TEST THIS (also test tabs) - pop.text(nil, "This is a test\ncollection of strings to see how width is determined.\nLooks like it takes width of widest line!"):move(30, 120) - pop.element():align("right", "bottom"):setSize(25, 25):move(-5, -5) + pop:text(nil, "This is a test\ncollection of strings to see how width is determined.\nLooks like it takes width of widest line!"):move(30, 120) + pop:element():align("right", "bottom"):setSize(25, 25):move(-5, -5) end function love.update(dt) - pop.update(dt) + pop:update(dt) end function love.draw() - pop.draw() + pop:draw() if debugDrawEnabled then - pop.debugDraw() + pop:debugDraw() end end function love.textinput(text) - --pop.textinput(text) + --pop:textinput(text) end function love.mousepressed(button, x, y) - --pop.mousepressed(button, x, y) + --pop:mousepressed(button, x, y) end function love.mousereleased(button, x, y) - --pop.mousereleased(button, x, y) + --pop:mousereleased(button, x, y) end function love.keypressed(key) @@ -44,19 +44,19 @@ function love.keypressed(key) else if (key == "s") and (not visualTestsShown) then -- old visual tests - local align = pop.box():align("center", "center"):setSize(200, 200) - pop.box(align):align("left", "top"):setSize(75, 10):setColor(255, 0, 255, 255) - pop.box(align):align("center", "top"):setColor(100, 100, 100) - pop.box(align, {0, 255, 0, 255}):setSize(20, 5):align("right", "top") - pop.box(align):align("left", "center"):setColor(0, 0, 255) - pop.box(align):align("center", "center"):setSize(90, 90):setColor(255, 255, 255) - pop.box(align):align("right", "center"):setColor(255, 0, 0) - pop.box(align):align("left", "bottom"):setColor(0, 255, 0):setSize(nil, 40) - pop.box(align):align("center", "bottom"):setColor(255, 255, 0) - pop.box(align):align("right", "bottom"):setColor(0, 255, 255):setSize(40, 40) - --pop.box(nil, {255, 0, 0, 255}):align("left", "top"):setSize(50, 50) --TODO adjust z-height of elements - pop.text(nil, "Hello World!"):align("center"):setText("Hey, I've been modified!")--:move(0, 18) - pop.text(nil, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()-=_+[]{}\\|:;\"',./<>?`~"):align("center", "bottom") + local align = pop:box():align("center", "center"):setSize(200, 200) + pop:box(align):align("left", "top"):setSize(75, 10):setColor(255, 0, 255, 255) + pop:box(align):align("center", "top"):setColor(100, 100, 100) + pop:box(align, {0, 255, 0, 255}):setSize(20, 5):align("right", "top") + pop:box(align):align("left", "center"):setColor(0, 0, 255) + pop:box(align):align("center", "center"):setSize(90, 90):setColor(255, 255, 255) + pop:box(align):align("right", "center"):setColor(255, 0, 0) + pop:box(align):align("left", "bottom"):setColor(0, 255, 0):setSize(nil, 40) + pop:box(align):align("center", "bottom"):setColor(255, 255, 0) + pop:box(align):align("right", "bottom"):setColor(0, 255, 255):setSize(40, 40) + --pop:box(nil, {255, 0, 0, 255}):align("left", "top"):setSize(50, 50) --TODO adjust z-height of elements + pop:text(nil, "Hello World!"):align("center"):setText("Hey, I've been modified!")--:move(0, 18) + pop:text(nil, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()-=_+[]{}\\|:;\"',./<>?`~"):align("center", "bottom") visualTestsShown = true elseif (key == "t") and (not testsRun) then @@ -65,10 +65,10 @@ function love.keypressed(key) debugDrawEnabled = not debugDrawEnabled end - --pop.keypressed(key) + --pop:keypressed(key) end end function love.keyreleased(key) - --pop.keyreleased(key) + --pop:keyreleased(key) end diff --git a/demo/pop/elements/box.lua b/demo/pop/elements/box.lua new file mode 100644 index 0000000..f1cc1b6 --- /dev/null +++ b/demo/pop/elements/box.lua @@ -0,0 +1,103 @@ +local graphics +graphics = love.graphics +local sub, len +do + local _obj_0 = string + sub, len = _obj_0.sub, _obj_0.len +end +local path = sub(..., 1, len(...) - len("/box")) +local element = require(tostring(path) .. "/element") +local box +do + local _class_0 + local _parent_0 = element + local _base_0 = { + draw = function(self) + if self.background then + if type(self.background) == "table" then + graphics.setColor(self.background) + else + graphics.setColor(self.background) + local w, h = self.background:getDimensions() + w = self.w / w + h = self.h / h + graphics.draw(self.background, self.x, self.y, 0, w, h) + end + end + return self + end, + debugDraw = function(self) + graphics.setLineWidth(0.5) + graphics.setColor(0, 0, 0, 100) + graphics.rectangle("fill", self.x, self.y, self.w, self.h) + graphics.setColor(0, 0, 200, 200) + graphics.rectangle("line", self.x, self.y, self.w, self.h) + graphics.setColor(200, 200, 255, 255) + graphics.print("b", self.x, self.y) + return self + end, + setBackground = function(self, background) + self.background = background + return self + end, + getBackground = function(self) + return self.background + end, + setColor = function(self, r, g, b, a) + if a == nil then + a = 255 + end + self.background = { + r, + g, + b, + a + } + return self + end, + getColor = function(self) + if type(self.background) == "table" then + return unpack(self.background) + else + return error("This box doesn't have a color.") + end + end + } + _base_0.__index = _base_0 + setmetatable(_base_0, _parent_0.__base) + _class_0 = setmetatable({ + __init = function(self, pop, parent, background) + if background == nil then + background = false + end + _class_0.__parent.__init(self, pop, parent) + self.background = background + end, + __base = _base_0, + __name = "box", + __parent = _parent_0 + }, { + __index = function(cls, name) + local val = rawget(_base_0, name) + if val == nil then + local parent = rawget(cls, "__parent") + if parent then + return parent[name] + end + else + return val + end + end, + __call = function(cls, ...) + local _self_0 = setmetatable({}, _base_0) + cls.__init(_self_0, ...) + return _self_0 + end + }) + _base_0.__class = _class_0 + if _parent_0.__inherited then + _parent_0.__inherited(_parent_0, _class_0) + end + box = _class_0 + return _class_0 +end diff --git a/demo/pop/elements/element.lua b/demo/pop/elements/element.lua new file mode 100644 index 0000000..12bcfe5 --- /dev/null +++ b/demo/pop/elements/element.lua @@ -0,0 +1,170 @@ +local graphics +graphics = love.graphics +local element +do + local _class_0 + local _base_0 = { + debugDraw = function(self) + graphics.setLineWidth(0.5) + graphics.setColor(0, 0, 0, 100) + graphics.rectangle("fill", self.x, self.y, self.w, self.h) + graphics.setColor(0, 200, 0, 200) + graphics.rectangle("line", self.x, self.y, self.w, self.h) + graphics.setColor(200, 255, 200, 255) + graphics.print("e", self.x, self.y) + return self + end, + move = function(self, x, y) + self.x = self.x + x + self.y = self.y + y + for i = 1, #self.child do + if not self.child[i].excludeMovement then + self.child[i]:move(x, y) + end + end + return self + end, + setPosition = function(self, x, y) + local oldX = self.x + local oldY = self.y + local _exp_0 = self.horizontal + if "left" == _exp_0 then + self.x = x + elseif "center" == _exp_0 then + self.x = x - self.w / 2 + elseif "right" == _exp_0 then + self.x = x - self.w + end + local _exp_1 = self.vertical + if "top" == _exp_1 then + self.y = y + elseif "center" == _exp_1 then + self.y = y - self.h / 2 + elseif "bottom" == _exp_1 then + self.y = y - self.h + end + for i = 1, #self.child do + if not self.child[i].excludeMovement then + self.child[i]:move(x - oldX, y - oldY) + end + end + return self + end, + getPosition = function(self) + local resultX = self.x + local resultY = self.y + local _exp_0 = self.horizontal + if "center" == _exp_0 then + resultX = resultX + (self.w / 2) + elseif "right" == _exp_0 then + resultX = resultX + self.w + end + local _exp_1 = self.vertical + if "center" == _exp_1 then + resultY = resultY + (self.h / 2) + elseif "bottom" == _exp_1 then + resultY = resultY + self.h + end + return resultX, resultY + end, + setSize = function(self, w, h) + if w then + local _exp_0 = self.horizontal + if "center" == _exp_0 then + self.x = self.x - ((w - self.w) / 2) + elseif "right" == _exp_0 then + self.x = self.x - (w - self.w) + end + self.w = w + end + if h then + local _exp_0 = self.vertical + if "center" == _exp_0 then + self.y = self.y - ((h - self.h) / 2) + elseif "bottom" == _exp_0 then + self.y = self.y - (h - self.h) + end + self.h = h + end + return self + end, + getSize = function(self) + return self.w, self.h + end, + adjustSize = function(self, w, h) + local W, H = self:getSize() + if w then + W = W + w + end + if h then + H = H + h + end + self:setSize(W, H) + return self + end, + align = function(self, horizontal, vertical) + self:setAlignment(horizontal, vertical) + self.x = self.parent.x + self.y = self.parent.y + local _exp_0 = self.horizontal + if "left" == _exp_0 then + self.x = self.x + self.margin + elseif "center" == _exp_0 then + self.x = self.x + ((self.parent.w - self.w) / 2) + elseif "right" == _exp_0 then + self.x = self.x + (self.parent.w - self.w - self.margin) + end + local _exp_1 = self.vertical + if "top" == _exp_1 then + self.y = self.y + self.margin + elseif "center" == _exp_1 then + self.y = self.y + ((self.parent.h - self.h) / 2) + elseif "bottom" == _exp_1 then + self.y = self.y + (self.parent.h - self.h - self.margin) + end + return self + end, + alignTo = function(self, element, horizontal, vertical) + local realParent = self.parent + self.parent = element + self:align(horizontal, vertical) + self.parent = realParent + return self + end, + setAlignment = function(self, horizontal, vertical) + if horizontal then + self.horizontal = horizontal + end + if vertical then + self.vertical = vertical + end + return self + end + } + _base_0.__index = _base_0 + _class_0 = setmetatable({ + __init = function(self, pop, parent) + self.parent = parent + self.child = { } + self.x = parent.x or 0 + self.y = parent.y or 0 + self.w = 10 + self.h = 10 + self.horizontal = "left" + self.vertical = "top" + self.margin = 0 + end, + __base = _base_0, + __name = "element" + }, { + __index = _base_0, + __call = function(cls, ...) + local _self_0 = setmetatable({}, _base_0) + cls.__init(_self_0, ...) + return _self_0 + end + }) + _base_0.__class = _class_0 + element = _class_0 + return _class_0 +end diff --git a/demo/pop/elements/text.lua b/demo/pop/elements/text.lua new file mode 100644 index 0000000..cebc19f --- /dev/null +++ b/demo/pop/elements/text.lua @@ -0,0 +1,132 @@ +local graphics +graphics = love.graphics +local sub, len +do + local _obj_0 = string + sub, len = _obj_0.sub, _obj_0.len +end +local path = sub(..., 1, len(...) - len("/text")) +local element = require(tostring(path) .. "/element") +local text +do + local _class_0 + local _parent_0 = element + local _base_0 = { + draw = function(self) + graphics.setColor(self.color) + graphics.setFont(self.font) + graphics.print(self.text, self.x, self.y) + return self + end, + debugDraw = function(self) + graphics.setLineWidth(0.5) + graphics.setColor(0, 0, 0, 100) + graphics.rectangle("fill", self.x, self.y, self.w, self.h) + graphics.setColor(200, 0, 0, 200) + graphics.rectangle("line", self.x, self.y, self.w, self.h) + graphics.setColor(255, 200, 200, 255) + graphics.print("t", self.x, self.y) + return self + end, + setSize = function(self) + local w = self.font:getWidth(self.text) + local h = self.font:getHeight() * (select(2, self.text:gsub("\n", "\n")) + 1) + local _exp_0 = self.horizontal + if "center" == _exp_0 then + self.x = self.x - ((w - self.w) / 2) + elseif "right" == _exp_0 then + self.x = self.x - (w - self.w - self.margin) + end + local _exp_1 = self.vertical + if "center" == _exp_1 then + self.y = self.y - ((h - self.h) / 2) + elseif "right" == _exp_1 then + self.y = self.y - (h - self.h - self.margin) + end + self.w = w + self.h = h + return self + end, + setText = function(self, text) + if text == nil then + text = "" + end + self.text = text + self:setSize() + return self + end, + getText = function(self) + return self.text + end, + setFont = function(self, font) + self.font = font + self:setSize() + return self + end, + getFont = function(self) + return self.font + end, + setColor = function(self, r, g, b, a) + if a == nil then + a = 255 + end + self.color = { + r, + g, + b, + a + } + return self + end, + getColor = function(self) + return unpack(self.color) + end + } + _base_0.__index = _base_0 + setmetatable(_base_0, _parent_0.__base) + _class_0 = setmetatable({ + __init = function(self, pop, parent, text, color) + if text == nil then + text = "" + end + if color == nil then + color = { + 255, + 255, + 255, + 255 + } + end + _class_0.__parent.__init(self, pop, parent) + self.font = graphics.newFont(14) + self:setText(text) + self.color = color + end, + __base = _base_0, + __name = "text", + __parent = _parent_0 + }, { + __index = function(cls, name) + local val = rawget(_base_0, name) + if val == nil then + local parent = rawget(cls, "__parent") + if parent then + return parent[name] + end + else + return val + end + end, + __call = function(cls, ...) + local _self_0 = setmetatable({}, _base_0) + cls.__init(_self_0, ...) + return _self_0 + end + }) + _base_0.__class = _class_0 + if _parent_0.__inherited then + _parent_0.__inherited(_parent_0, _class_0) + end + text = _class_0 + return _class_0 +end diff --git a/demo/pop/init.lua b/demo/pop/init.lua new file mode 100644 index 0000000..f9ec126 --- /dev/null +++ b/demo/pop/init.lua @@ -0,0 +1,176 @@ +local filesystem, graphics +do + local _obj_0 = love + filesystem, graphics = _obj_0.filesystem, _obj_0.graphics +end +local insert +insert = table.insert +local path = ... +local Pop +do + local _class_0 + local _base_0 = { + create = function(self, elementType, parent, ...) + if parent == nil then + parent = self.window + end + local newElement = self.elements[elementType](parent, ...) + insert(parent.child, newElement) + return newElement + end, + update = function(self, dt, element) + if element == nil then + element = self.window + end + if not element.excludeUpdating then + if element.update then + element:update(dt) + end + for i = 1, #element.child do + self:update(dt, element.child[i]) + end + end + end, + draw = function(self, element) + if element == nil then + element = self.window + end + if not element.excludeRendering then + if element.draw then + local _ + do + local _base_1 = element + local _fn_0 = _base_1.draw + _ = function(...) + return _fn_0(_base_1, ...) + end + end + end + for i = 1, #element.child do + self:draw(element.child[i]) + end + end + end, + mousepressed = function(self, button, x, y, element) + if element == nil then + element = self.window + end + if (x >= element.x) and (x <= (element.x + element.w)) then + if (y >= element.y) and (y <= (element.y + element.h)) then + for i = 1, #element.child do + if self:mousepressed(button, x, y, element.child[i]) then + return true + end + end + if element.mousepressed then + return element:mousepressed(button, x - element.x, y - element.y) + else + return false + end + end + end + end, + mousereleased = function(self, button, x, y, element) + if element == nil then + element = self.window + end + if (x >= element.x) and (x <= (element.x + element.w)) then + if (y >= element.y) and (y <= (element.y + element.h)) then + for i = 1, #element.child do + if self:mousereleased(button, x, y, element.child[i]) then + return true + end + end + if element.mousereleased then + return element:mousereleased(button, x - element.x, y - element.y) + else + return false + end + end + end + end, + keypressed = function(self, key) + return error("Unimplemented.") + end, + keyreleased = function(self, key) + return error("Unimplemented.") + end, + textinput = function(self, text) + return error("Unimplemented.") + end, + skin = function(self, element, skin, apply_to_children) + if apply_to_children == nil then + apply_to_children = true + end + element.margin = skin.margin + if element.background then + element.background = skin.background + end + if element.color then + element.color = skin.color + end + if element.font then + element.font = skin.font + end + if apply_to_children then + for i = 1, #element.child do + self:skin(element.child[i], skin) + end + end + end, + debugDraw = function(self, element) + if element == nil then + element = self.window + end + if element.debugDraw then + element:debugDraw() + else + graphics.setLineWidth(1) + graphics.setColor(0, 0, 0, 100) + graphics.rectangle("fill", element.x, element.y, element.w, element.h) + graphics.setColor(150, 150, 150, 150) + graphics.rectangle("line", element.x, element.y, element.w, element.h) + graphics.setColor(200, 200, 200, 255) + graphics.print(".", element.x, element.y) + end + for i = 1, #element.child do + self:debugDraw(element.child[i]) + end + end + } + _base_0.__index = _base_0 + _class_0 = setmetatable({ + __init = function(self) + self.elements = { } + self.window = { + child = { } + } + local elements = filesystem.getDirectoryItems(tostring(path) .. "/elements") + for i = 1, #elements do + local name = elements[i]:sub(1, -5) + self.elements[name] = require(tostring(path) .. "/elements/" .. tostring(name)) + print("loaded element: " .. tostring(name)) + if not self[name] then + self[name] = function(self, ...) + return self:create(name, ...) + end + print("wrapper created: " .. tostring(name) .. "()") + end + end + self.window = self:create("element", self.window):setSize(graphics.getWidth(), graphics.getHeight()) + return print("created window") + end, + __base = _base_0, + __name = "Pop" + }, { + __index = _base_0, + __call = function(cls, ...) + local _self_0 = setmetatable({}, _base_0) + cls.__init(_self_0, ...) + return _self_0 + end + }) + _base_0.__class = _class_0 + Pop = _class_0 + return _class_0 +end diff --git a/demo/pop/skins/clear.lua b/demo/pop/skins/clear.lua new file mode 100644 index 0000000..87ed6fd --- /dev/null +++ b/demo/pop/skins/clear.lua @@ -0,0 +1,13 @@ +local graphics +graphics = love.graphics +return { + color = { + 255, + 255, + 255, + 255 + }, + background = false, + font = graphics.newFont(13), + margin = 2 +} diff --git a/lib/pop/elements/box.lua b/lib/pop/elements/box.lua new file mode 100644 index 0000000..f1cc1b6 --- /dev/null +++ b/lib/pop/elements/box.lua @@ -0,0 +1,103 @@ +local graphics +graphics = love.graphics +local sub, len +do + local _obj_0 = string + sub, len = _obj_0.sub, _obj_0.len +end +local path = sub(..., 1, len(...) - len("/box")) +local element = require(tostring(path) .. "/element") +local box +do + local _class_0 + local _parent_0 = element + local _base_0 = { + draw = function(self) + if self.background then + if type(self.background) == "table" then + graphics.setColor(self.background) + else + graphics.setColor(self.background) + local w, h = self.background:getDimensions() + w = self.w / w + h = self.h / h + graphics.draw(self.background, self.x, self.y, 0, w, h) + end + end + return self + end, + debugDraw = function(self) + graphics.setLineWidth(0.5) + graphics.setColor(0, 0, 0, 100) + graphics.rectangle("fill", self.x, self.y, self.w, self.h) + graphics.setColor(0, 0, 200, 200) + graphics.rectangle("line", self.x, self.y, self.w, self.h) + graphics.setColor(200, 200, 255, 255) + graphics.print("b", self.x, self.y) + return self + end, + setBackground = function(self, background) + self.background = background + return self + end, + getBackground = function(self) + return self.background + end, + setColor = function(self, r, g, b, a) + if a == nil then + a = 255 + end + self.background = { + r, + g, + b, + a + } + return self + end, + getColor = function(self) + if type(self.background) == "table" then + return unpack(self.background) + else + return error("This box doesn't have a color.") + end + end + } + _base_0.__index = _base_0 + setmetatable(_base_0, _parent_0.__base) + _class_0 = setmetatable({ + __init = function(self, pop, parent, background) + if background == nil then + background = false + end + _class_0.__parent.__init(self, pop, parent) + self.background = background + end, + __base = _base_0, + __name = "box", + __parent = _parent_0 + }, { + __index = function(cls, name) + local val = rawget(_base_0, name) + if val == nil then + local parent = rawget(cls, "__parent") + if parent then + return parent[name] + end + else + return val + end + end, + __call = function(cls, ...) + local _self_0 = setmetatable({}, _base_0) + cls.__init(_self_0, ...) + return _self_0 + end + }) + _base_0.__class = _class_0 + if _parent_0.__inherited then + _parent_0.__inherited(_parent_0, _class_0) + end + box = _class_0 + return _class_0 +end diff --git a/lib/pop/elements/element.lua b/lib/pop/elements/element.lua new file mode 100644 index 0000000..12bcfe5 --- /dev/null +++ b/lib/pop/elements/element.lua @@ -0,0 +1,170 @@ +local graphics +graphics = love.graphics +local element +do + local _class_0 + local _base_0 = { + debugDraw = function(self) + graphics.setLineWidth(0.5) + graphics.setColor(0, 0, 0, 100) + graphics.rectangle("fill", self.x, self.y, self.w, self.h) + graphics.setColor(0, 200, 0, 200) + graphics.rectangle("line", self.x, self.y, self.w, self.h) + graphics.setColor(200, 255, 200, 255) + graphics.print("e", self.x, self.y) + return self + end, + move = function(self, x, y) + self.x = self.x + x + self.y = self.y + y + for i = 1, #self.child do + if not self.child[i].excludeMovement then + self.child[i]:move(x, y) + end + end + return self + end, + setPosition = function(self, x, y) + local oldX = self.x + local oldY = self.y + local _exp_0 = self.horizontal + if "left" == _exp_0 then + self.x = x + elseif "center" == _exp_0 then + self.x = x - self.w / 2 + elseif "right" == _exp_0 then + self.x = x - self.w + end + local _exp_1 = self.vertical + if "top" == _exp_1 then + self.y = y + elseif "center" == _exp_1 then + self.y = y - self.h / 2 + elseif "bottom" == _exp_1 then + self.y = y - self.h + end + for i = 1, #self.child do + if not self.child[i].excludeMovement then + self.child[i]:move(x - oldX, y - oldY) + end + end + return self + end, + getPosition = function(self) + local resultX = self.x + local resultY = self.y + local _exp_0 = self.horizontal + if "center" == _exp_0 then + resultX = resultX + (self.w / 2) + elseif "right" == _exp_0 then + resultX = resultX + self.w + end + local _exp_1 = self.vertical + if "center" == _exp_1 then + resultY = resultY + (self.h / 2) + elseif "bottom" == _exp_1 then + resultY = resultY + self.h + end + return resultX, resultY + end, + setSize = function(self, w, h) + if w then + local _exp_0 = self.horizontal + if "center" == _exp_0 then + self.x = self.x - ((w - self.w) / 2) + elseif "right" == _exp_0 then + self.x = self.x - (w - self.w) + end + self.w = w + end + if h then + local _exp_0 = self.vertical + if "center" == _exp_0 then + self.y = self.y - ((h - self.h) / 2) + elseif "bottom" == _exp_0 then + self.y = self.y - (h - self.h) + end + self.h = h + end + return self + end, + getSize = function(self) + return self.w, self.h + end, + adjustSize = function(self, w, h) + local W, H = self:getSize() + if w then + W = W + w + end + if h then + H = H + h + end + self:setSize(W, H) + return self + end, + align = function(self, horizontal, vertical) + self:setAlignment(horizontal, vertical) + self.x = self.parent.x + self.y = self.parent.y + local _exp_0 = self.horizontal + if "left" == _exp_0 then + self.x = self.x + self.margin + elseif "center" == _exp_0 then + self.x = self.x + ((self.parent.w - self.w) / 2) + elseif "right" == _exp_0 then + self.x = self.x + (self.parent.w - self.w - self.margin) + end + local _exp_1 = self.vertical + if "top" == _exp_1 then + self.y = self.y + self.margin + elseif "center" == _exp_1 then + self.y = self.y + ((self.parent.h - self.h) / 2) + elseif "bottom" == _exp_1 then + self.y = self.y + (self.parent.h - self.h - self.margin) + end + return self + end, + alignTo = function(self, element, horizontal, vertical) + local realParent = self.parent + self.parent = element + self:align(horizontal, vertical) + self.parent = realParent + return self + end, + setAlignment = function(self, horizontal, vertical) + if horizontal then + self.horizontal = horizontal + end + if vertical then + self.vertical = vertical + end + return self + end + } + _base_0.__index = _base_0 + _class_0 = setmetatable({ + __init = function(self, pop, parent) + self.parent = parent + self.child = { } + self.x = parent.x or 0 + self.y = parent.y or 0 + self.w = 10 + self.h = 10 + self.horizontal = "left" + self.vertical = "top" + self.margin = 0 + end, + __base = _base_0, + __name = "element" + }, { + __index = _base_0, + __call = function(cls, ...) + local _self_0 = setmetatable({}, _base_0) + cls.__init(_self_0, ...) + return _self_0 + end + }) + _base_0.__class = _class_0 + element = _class_0 + return _class_0 +end diff --git a/lib/pop/elements/text.lua b/lib/pop/elements/text.lua new file mode 100644 index 0000000..cebc19f --- /dev/null +++ b/lib/pop/elements/text.lua @@ -0,0 +1,132 @@ +local graphics +graphics = love.graphics +local sub, len +do + local _obj_0 = string + sub, len = _obj_0.sub, _obj_0.len +end +local path = sub(..., 1, len(...) - len("/text")) +local element = require(tostring(path) .. "/element") +local text +do + local _class_0 + local _parent_0 = element + local _base_0 = { + draw = function(self) + graphics.setColor(self.color) + graphics.setFont(self.font) + graphics.print(self.text, self.x, self.y) + return self + end, + debugDraw = function(self) + graphics.setLineWidth(0.5) + graphics.setColor(0, 0, 0, 100) + graphics.rectangle("fill", self.x, self.y, self.w, self.h) + graphics.setColor(200, 0, 0, 200) + graphics.rectangle("line", self.x, self.y, self.w, self.h) + graphics.setColor(255, 200, 200, 255) + graphics.print("t", self.x, self.y) + return self + end, + setSize = function(self) + local w = self.font:getWidth(self.text) + local h = self.font:getHeight() * (select(2, self.text:gsub("\n", "\n")) + 1) + local _exp_0 = self.horizontal + if "center" == _exp_0 then + self.x = self.x - ((w - self.w) / 2) + elseif "right" == _exp_0 then + self.x = self.x - (w - self.w - self.margin) + end + local _exp_1 = self.vertical + if "center" == _exp_1 then + self.y = self.y - ((h - self.h) / 2) + elseif "right" == _exp_1 then + self.y = self.y - (h - self.h - self.margin) + end + self.w = w + self.h = h + return self + end, + setText = function(self, text) + if text == nil then + text = "" + end + self.text = text + self:setSize() + return self + end, + getText = function(self) + return self.text + end, + setFont = function(self, font) + self.font = font + self:setSize() + return self + end, + getFont = function(self) + return self.font + end, + setColor = function(self, r, g, b, a) + if a == nil then + a = 255 + end + self.color = { + r, + g, + b, + a + } + return self + end, + getColor = function(self) + return unpack(self.color) + end + } + _base_0.__index = _base_0 + setmetatable(_base_0, _parent_0.__base) + _class_0 = setmetatable({ + __init = function(self, pop, parent, text, color) + if text == nil then + text = "" + end + if color == nil then + color = { + 255, + 255, + 255, + 255 + } + end + _class_0.__parent.__init(self, pop, parent) + self.font = graphics.newFont(14) + self:setText(text) + self.color = color + end, + __base = _base_0, + __name = "text", + __parent = _parent_0 + }, { + __index = function(cls, name) + local val = rawget(_base_0, name) + if val == nil then + local parent = rawget(cls, "__parent") + if parent then + return parent[name] + end + else + return val + end + end, + __call = function(cls, ...) + local _self_0 = setmetatable({}, _base_0) + cls.__init(_self_0, ...) + return _self_0 + end + }) + _base_0.__class = _class_0 + if _parent_0.__inherited then + _parent_0.__inherited(_parent_0, _class_0) + end + text = _class_0 + return _class_0 +end diff --git a/lib/pop/init.lua b/lib/pop/init.lua new file mode 100644 index 0000000..f9ec126 --- /dev/null +++ b/lib/pop/init.lua @@ -0,0 +1,176 @@ +local filesystem, graphics +do + local _obj_0 = love + filesystem, graphics = _obj_0.filesystem, _obj_0.graphics +end +local insert +insert = table.insert +local path = ... +local Pop +do + local _class_0 + local _base_0 = { + create = function(self, elementType, parent, ...) + if parent == nil then + parent = self.window + end + local newElement = self.elements[elementType](parent, ...) + insert(parent.child, newElement) + return newElement + end, + update = function(self, dt, element) + if element == nil then + element = self.window + end + if not element.excludeUpdating then + if element.update then + element:update(dt) + end + for i = 1, #element.child do + self:update(dt, element.child[i]) + end + end + end, + draw = function(self, element) + if element == nil then + element = self.window + end + if not element.excludeRendering then + if element.draw then + local _ + do + local _base_1 = element + local _fn_0 = _base_1.draw + _ = function(...) + return _fn_0(_base_1, ...) + end + end + end + for i = 1, #element.child do + self:draw(element.child[i]) + end + end + end, + mousepressed = function(self, button, x, y, element) + if element == nil then + element = self.window + end + if (x >= element.x) and (x <= (element.x + element.w)) then + if (y >= element.y) and (y <= (element.y + element.h)) then + for i = 1, #element.child do + if self:mousepressed(button, x, y, element.child[i]) then + return true + end + end + if element.mousepressed then + return element:mousepressed(button, x - element.x, y - element.y) + else + return false + end + end + end + end, + mousereleased = function(self, button, x, y, element) + if element == nil then + element = self.window + end + if (x >= element.x) and (x <= (element.x + element.w)) then + if (y >= element.y) and (y <= (element.y + element.h)) then + for i = 1, #element.child do + if self:mousereleased(button, x, y, element.child[i]) then + return true + end + end + if element.mousereleased then + return element:mousereleased(button, x - element.x, y - element.y) + else + return false + end + end + end + end, + keypressed = function(self, key) + return error("Unimplemented.") + end, + keyreleased = function(self, key) + return error("Unimplemented.") + end, + textinput = function(self, text) + return error("Unimplemented.") + end, + skin = function(self, element, skin, apply_to_children) + if apply_to_children == nil then + apply_to_children = true + end + element.margin = skin.margin + if element.background then + element.background = skin.background + end + if element.color then + element.color = skin.color + end + if element.font then + element.font = skin.font + end + if apply_to_children then + for i = 1, #element.child do + self:skin(element.child[i], skin) + end + end + end, + debugDraw = function(self, element) + if element == nil then + element = self.window + end + if element.debugDraw then + element:debugDraw() + else + graphics.setLineWidth(1) + graphics.setColor(0, 0, 0, 100) + graphics.rectangle("fill", element.x, element.y, element.w, element.h) + graphics.setColor(150, 150, 150, 150) + graphics.rectangle("line", element.x, element.y, element.w, element.h) + graphics.setColor(200, 200, 200, 255) + graphics.print(".", element.x, element.y) + end + for i = 1, #element.child do + self:debugDraw(element.child[i]) + end + end + } + _base_0.__index = _base_0 + _class_0 = setmetatable({ + __init = function(self) + self.elements = { } + self.window = { + child = { } + } + local elements = filesystem.getDirectoryItems(tostring(path) .. "/elements") + for i = 1, #elements do + local name = elements[i]:sub(1, -5) + self.elements[name] = require(tostring(path) .. "/elements/" .. tostring(name)) + print("loaded element: " .. tostring(name)) + if not self[name] then + self[name] = function(self, ...) + return self:create(name, ...) + end + print("wrapper created: " .. tostring(name) .. "()") + end + end + self.window = self:create("element", self.window):setSize(graphics.getWidth(), graphics.getHeight()) + return print("created window") + end, + __base = _base_0, + __name = "Pop" + }, { + __index = _base_0, + __call = function(cls, ...) + local _self_0 = setmetatable({}, _base_0) + cls.__init(_self_0, ...) + return _self_0 + end + }) + _base_0.__class = _class_0 + Pop = _class_0 + return _class_0 +end diff --git a/lib/pop/skins/clear.lua b/lib/pop/skins/clear.lua new file mode 100644 index 0000000..87ed6fd --- /dev/null +++ b/lib/pop/skins/clear.lua @@ -0,0 +1,13 @@ +local graphics +graphics = love.graphics +return { + color = { + 255, + 255, + 255, + 255 + }, + background = false, + font = graphics.newFont(13), + margin = 2 +} diff --git a/run demo.bat b/run demo.bat new file mode 100644 index 0000000..a5b9168 --- /dev/null +++ b/run demo.bat @@ -0,0 +1,2 @@ +@ECHO OFF +"C:\Program Files\Love\LOVE.exe" "%cd%\demo" diff --git a/src/pop/elements/element.moon b/src/pop/elements/element.moon index 37547ce..dc7b028 100644 --- a/src/pop/elements/element.moon +++ b/src/pop/elements/element.moon @@ -29,7 +29,7 @@ class element @x += x @y += y - for i in @child do + for i = 1, #@child if not @child[i].excludeMovement @child[i]\move x, y @@ -55,7 +55,7 @@ class element when "bottom" @y = y - @h - for i in @child + for i = 1, #@child if not @child[i].excludeMovement @child[i]\move x - oldX, y - oldY @@ -86,6 +86,7 @@ class element @x -= (w - @w)/2 when "right" @x -= w - @w + @w = w if h diff --git a/src/pop/elements/text.moon b/src/pop/elements/text.moon index 53a3232..63e77d3 100644 --- a/src/pop/elements/text.moon +++ b/src/pop/elements/text.moon @@ -32,7 +32,7 @@ class text extends element setSize: => w = @font\getWidth @text - h = @font\getHeight * (select(2, @text:gsub("\n", "\n")) + 1) --hack to get height of multiple lines of text + h = @font\getHeight! * (select(2, @text\gsub("\n", "\n")) + 1) --hack to get height of multiple lines of text switch @horizontal when "center" diff --git a/src/pop/init.moon b/src/pop/init.moon index 7d1ce89..f68191e 100644 --- a/src/pop/init.moon +++ b/src/pop/init.moon @@ -6,24 +6,26 @@ path = ... class Pop new: => @elements = {} - @window = {child: {}} --TODO eliminate this crap + @window = {child: {}} --@focused = @window --TODO redo better elements = filesystem.getDirectoryItems "#{path}/elements" - for i in elements + for i = 1, #elements name = elements[i]\sub 1, -5 @elements[name] = require "#{path}/elements/#{name}" print "loaded element: #{name}" - if not @name - @name = (...) -> return @create(name, ...) - print "wrapped created: #{name}()" + if not @[name] + @[name] = (...) => return @create(name, ...) + print "wrapper created: #{name}()" - @window = @create("element")\setSize(graphics.getWidth!, graphics.getHeight!) + @window = @create("element", @window)\setSize(graphics.getWidth!, graphics.getHeight!) print "created window" + --@window.parent = @window + --@window.parent = false create: (elementType, parent=@window, ...) => - newElement = @elements[elementType](@, parent, ...) + newElement = @elements[elementType](parent, ...) insert parent.child, newElement return newElement @@ -32,7 +34,7 @@ class Pop if element.update element\update dt - for i in element.child + for i = 1, #element.child @update dt, element.child[i] draw: (element=@window) => @@ -40,14 +42,38 @@ class Pop if element.draw element\draw - for i in element.child + for i = 1, #element.child @draw element.child[i] - mousepressed: (button, x, y, element) => - error "Unimplemented." + mousepressed: (button, x, y, element=@window) => + -- if within bounds of element, check its children + -- if not handled by child, check if it can handle it + -- abort loop with success if handled + if (x >= element.x) and (x <= (element.x + element.w)) + if (y >= element.y) and (y <= (element.y + element.h)) + for i = 1, #element.child + if @mousepressed button, x, y, element.child[i] + return true - mousereleased: (button, x, y, element) => - error "Unimplemented." + if element.mousepressed + return element\mousepressed button, x - element.x, y - element.y + else + return false + + --TODO rewrite for multiple return values, mousereleased is the first val, click is the second! + mousereleased: (button, x, y, element=@window) => + -- same as mousepressed, except an additional click is fired + -- (TODO fix, so you have to start and end the click on the same element) + if (x >= element.x) and (x <= (element.x + element.w)) + if (y >= element.y) and (y <= (element.y + element.h)) + for i = 1, #element.child + if @mousereleased button, x, y, element.child[i] + return true + + if element.mousereleased + return element\mousereleased button, x - element.x, y - element.y + else + return false keypressed: (key) => error "Unimplemented." @@ -58,7 +84,7 @@ class Pop textinput: (text) => error "Unimplemented." - skin: (element, skin, apply_to_children=false) => + skin: (element, skin, apply_to_children=true) => element.margin = skin.margin if element.background @@ -68,8 +94,8 @@ class Pop if element.font element.font = skin.font - if not apply_to_children - for i in element.child + if apply_to_children + for i = 1, #element.child @skin element.child[i], skin debugDraw: (element=@window) => @@ -84,5 +110,5 @@ class Pop graphics.setColor 200, 200, 200, 255 graphics.print ".", element.x, element.y - for i in element.child + for i = 1, #element.child @debugDraw element.child[i] diff --git a/src/pop/skins/clear.moon b/src/pop/skins/clear.moon index bd8e0da..a283a0f 100644 --- a/src/pop/skins/clear.moon +++ b/src/pop/skins/clear.moon @@ -1,8 +1,8 @@ import graphics from love -skin = { +return { color: {255, 255, 255, 255} background: false - font: graphics.newFont(13) + font: graphics.newFont 13 margin: 2 }