mirror of
https://github.com/TangentFoxy/Pop.Box.git
synced 2024-12-15 12:44:20 +00:00
init crap
This commit is contained in:
commit
486f307274
24
README.md
Normal file
24
README.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Pop.Box
|
||||||
|
|
||||||
|
*Do not mix with [Cola][1].*
|
||||||
|
|
||||||
|
Pop.Box attempts to make a GUI system for use in the [LÖVE][2] engine that is
|
||||||
|
easy to use, requiring as little code as possible to get working, but also
|
||||||
|
extensible, allowing for complex interfaces to be built in it.
|
||||||
|
|
||||||
|
I've never written a GUI library before..so we'll see how that goes.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local pop = require "pop"
|
||||||
|
-- define love callbacks here
|
||||||
|
local box = pop.box()
|
||||||
|
```
|
||||||
|
|
||||||
|
* `box` is a box for containing things.
|
||||||
|
* `text` is a class for handling text.
|
||||||
|
* Nothing else! Is alpha, just started.
|
||||||
|
|
||||||
|
[1]: https://en.wikipedia.org/wiki/Cola_(programming_language)
|
||||||
|
[2]: https://love2d.org/
|
18
main.lua
Normal file
18
main.lua
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
local pop = require "pop"
|
||||||
|
|
||||||
|
function love.load()
|
||||||
|
pop.box() -- returns the box element
|
||||||
|
-- or pop.create("box") (this is what is actually called when you call pop.box())
|
||||||
|
end
|
||||||
|
|
||||||
|
function love.draw()
|
||||||
|
pop.draw()
|
||||||
|
end
|
||||||
|
|
||||||
|
function love.mousepressed(button, x, y)
|
||||||
|
pop.mousepressed(button, x, y)
|
||||||
|
end
|
||||||
|
|
||||||
|
function love.mousereleased(button, x, y)
|
||||||
|
pop.mousereleased(button, x, y)
|
||||||
|
end
|
24
pop/elements/box.lua
Normal file
24
pop/elements/box.lua
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
local path = string.sub(..., 1, string.len(...) - string.len(".elements.box"))
|
||||||
|
local class = require(path .. ".lib.middleclass")
|
||||||
|
local element = require(path .. ".elements.element")
|
||||||
|
|
||||||
|
local box = class("pop.box", element)
|
||||||
|
|
||||||
|
function box:initialize(pop, parent)
|
||||||
|
element.initialize(self, pop, parent)
|
||||||
|
self.sizeControl = "specified"
|
||||||
|
self.outerWidth = 300
|
||||||
|
self.outerHeight = 250
|
||||||
|
self.innerWidth = self.outerWidth - self.style.borderSize
|
||||||
|
self.innerHeight = self.outerHeight - self.style.borderSize
|
||||||
|
end
|
||||||
|
|
||||||
|
function box:update(pop)
|
||||||
|
--
|
||||||
|
end
|
||||||
|
|
||||||
|
function box:draw()
|
||||||
|
--TODO find a way for relative x/y to be passed here, because else, we won't have proper coords for drawing
|
||||||
|
end
|
||||||
|
|
||||||
|
return box
|
105
pop/elements/element.lua
Normal file
105
pop/elements/element.lua
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
local path = string.sub(..., 1, string.len(...) - string.len(".elements.element"))
|
||||||
|
local class = require(path .. ".lib.middleclass")
|
||||||
|
|
||||||
|
local element = class("pop.element") --NOTE are periods allowed in middleclass class names?
|
||||||
|
|
||||||
|
--TODO setting widths and heights need to call update()
|
||||||
|
--TODO setters and getters for just width/height, aliases for outerWidth/outerHeight
|
||||||
|
|
||||||
|
function element:initialize(pop, parent)
|
||||||
|
self.x = 0
|
||||||
|
self.y = 0
|
||||||
|
self.alignPoint = 1 -- 1 to 9, how aligned relative to x/y, see docs
|
||||||
|
|
||||||
|
self.sizeControl = "fromInner" -- fromInner, fromOuter, specified
|
||||||
|
self.outerWidth = 0
|
||||||
|
self.outerHeight = 0
|
||||||
|
self.innerWidth = 0
|
||||||
|
self.innerHeight = 0
|
||||||
|
|
||||||
|
self.style = pop.style
|
||||||
|
self.visible = true
|
||||||
|
|
||||||
|
self.parent = parent
|
||||||
|
self.child = {}
|
||||||
|
|
||||||
|
parent.child[self] = self -- add ourselves to the parent's children
|
||||||
|
end
|
||||||
|
|
||||||
|
function element:getAlignPoint()
|
||||||
|
return self.alignPoint
|
||||||
|
end
|
||||||
|
function element:setAlignPoint(point)
|
||||||
|
self.alignPoint = point
|
||||||
|
end
|
||||||
|
|
||||||
|
function element:getOuterWidth()
|
||||||
|
return self.outerWidth
|
||||||
|
end
|
||||||
|
function element:setOuterWidth(width)
|
||||||
|
assert(width > 0, "width must be above 0")
|
||||||
|
self.outerWidth = width
|
||||||
|
end
|
||||||
|
|
||||||
|
function element:getOuterHeight()
|
||||||
|
return self.outerHeight()
|
||||||
|
end
|
||||||
|
function element:setOuterHeight(height)
|
||||||
|
assert(height > 0, "height must be above 0")
|
||||||
|
self.outerHeight = height
|
||||||
|
end
|
||||||
|
|
||||||
|
function element:getInnerWidth()
|
||||||
|
return self.innerWidth
|
||||||
|
end
|
||||||
|
function element:setInnerWidth(width)
|
||||||
|
assert(width > 0, "width must be above 0")
|
||||||
|
self.innerWidth = width
|
||||||
|
end
|
||||||
|
|
||||||
|
function element:getInnerHeight()
|
||||||
|
return self.innerHeight
|
||||||
|
end
|
||||||
|
function element:setInnerHeight(height)
|
||||||
|
assert(height > 0, "height must be above 0")
|
||||||
|
self.innerHeight = height
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[ TODO determine how to write these better (consistency motherfucker)
|
||||||
|
function element:getStyle()
|
||||||
|
return self.style.name
|
||||||
|
end
|
||||||
|
function element:setStyle(style)
|
||||||
|
self.style = style
|
||||||
|
end
|
||||||
|
]]
|
||||||
|
|
||||||
|
function element:getVisible()
|
||||||
|
return self.visible
|
||||||
|
end
|
||||||
|
function element:setVisible(bool)
|
||||||
|
self.visible = bool
|
||||||
|
end
|
||||||
|
|
||||||
|
function element:getParent()
|
||||||
|
return self.parent
|
||||||
|
end
|
||||||
|
function element:setParent(parent)
|
||||||
|
self.parent.child[self] = nil
|
||||||
|
self.parent = parent
|
||||||
|
self.parent.child[self] = self
|
||||||
|
end
|
||||||
|
|
||||||
|
--TODO figure out how getting and setting children might work? or no??
|
||||||
|
|
||||||
|
function element:update()
|
||||||
|
--TODO a proper error message
|
||||||
|
print("update() not deifnenfei")
|
||||||
|
end
|
||||||
|
|
||||||
|
function element:draw()
|
||||||
|
--TODO figure out how to get class name
|
||||||
|
print("Attempting to use element, or did not overwrite element's :draw() method.")
|
||||||
|
end
|
||||||
|
|
||||||
|
return element
|
63
pop/init.lua
Normal file
63
pop/init.lua
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
local pop = {}
|
||||||
|
local path = ... -- this only works as long as the require() does't specify init.lua..which it shouldn't
|
||||||
|
|
||||||
|
-- elements are local
|
||||||
|
local box = require(path .. ".elements.box")
|
||||||
|
local text = require(path .. ".elements.text")
|
||||||
|
|
||||||
|
-- style defines how elements are drawn
|
||||||
|
pop.style = require(path .. ".skins.clear")
|
||||||
|
|
||||||
|
-- everything has one parent element (initialized at the end)
|
||||||
|
pop.parentElement = false
|
||||||
|
|
||||||
|
function pop.create(elementType, parent, ...)
|
||||||
|
if not parent then
|
||||||
|
parent = pop.parentElement
|
||||||
|
end
|
||||||
|
|
||||||
|
local newElement
|
||||||
|
|
||||||
|
if elementType == "box" then
|
||||||
|
newElement = box(pop, parent, ...)
|
||||||
|
elseif elementType == "text" then
|
||||||
|
newElement = text(pop, parent, ...)
|
||||||
|
else
|
||||||
|
error("Invalid element type: " .. elementType)
|
||||||
|
end
|
||||||
|
|
||||||
|
return newElement
|
||||||
|
end
|
||||||
|
|
||||||
|
-- pretty wrappers to call pop.element() instead of pop.create("element")
|
||||||
|
pop.box = function() return pop.create("box", ...) end
|
||||||
|
pop.text = function() return pop.create("text", ...) end
|
||||||
|
|
||||||
|
function pop.draw(element)
|
||||||
|
if not element then
|
||||||
|
element = pop.parentElement
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, childElements in pairs(element.child) do
|
||||||
|
--pop.draw(childElements, element.x, element.y)
|
||||||
|
pop.draw(childElements)
|
||||||
|
end
|
||||||
|
|
||||||
|
element:draw()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- TODO decide if we should track mouse movement
|
||||||
|
|
||||||
|
function pop.mousepressed(button, x, y)
|
||||||
|
--
|
||||||
|
end
|
||||||
|
|
||||||
|
function pop.mousereleased(button, x, y)
|
||||||
|
--
|
||||||
|
end
|
||||||
|
|
||||||
|
-- initialize the top element
|
||||||
|
pop.parentElement = box(pop, nil) -- nil because it has no parent
|
||||||
|
--pop.parentElement:setVisible(false) -- uneeded since its clear...
|
||||||
|
|
||||||
|
return pop
|
182
pop/lib/middleclass.lua
Normal file
182
pop/lib/middleclass.lua
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
local middleclass = {
|
||||||
|
_VERSION = 'middleclass v3.1.0',
|
||||||
|
_DESCRIPTION = 'Object Orientation for Lua',
|
||||||
|
_URL = 'https://github.com/kikito/middleclass',
|
||||||
|
_LICENSE = [[
|
||||||
|
MIT LICENSE
|
||||||
|
|
||||||
|
Copyright (c) 2011 Enrique García Cota
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included
|
||||||
|
in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
]]
|
||||||
|
}
|
||||||
|
|
||||||
|
local function _setClassDictionariesMetatables(aClass)
|
||||||
|
local dict = aClass.__instanceDict
|
||||||
|
dict.__index = dict
|
||||||
|
|
||||||
|
local super = aClass.super
|
||||||
|
if super then
|
||||||
|
local superStatic = super.static
|
||||||
|
setmetatable(dict, super.__instanceDict)
|
||||||
|
setmetatable(aClass.static, { __index = function(_,k) return rawget(dict,k) or superStatic[k] end })
|
||||||
|
else
|
||||||
|
setmetatable(aClass.static, { __index = function(_,k) return dict[k] end })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _setClassMetatable(aClass)
|
||||||
|
setmetatable(aClass, {
|
||||||
|
__tostring = function() return "class " .. aClass.name end,
|
||||||
|
__index = aClass.static,
|
||||||
|
__newindex = aClass.__instanceDict,
|
||||||
|
__call = function(self, ...) return self:new(...) end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _createClass(name, super)
|
||||||
|
local aClass = { name = name, super = super, static = {}, __mixins = {}, __instanceDict={} }
|
||||||
|
aClass.subclasses = setmetatable({}, {__mode = "k"})
|
||||||
|
|
||||||
|
_setClassDictionariesMetatables(aClass)
|
||||||
|
_setClassMetatable(aClass)
|
||||||
|
|
||||||
|
return aClass
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _createLookupMetamethod(aClass, name)
|
||||||
|
return function(...)
|
||||||
|
local method = aClass.super[name]
|
||||||
|
assert( type(method)=='function', tostring(aClass) .. " doesn't implement metamethod '" .. name .. "'" )
|
||||||
|
return method(...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _setClassMetamethods(aClass)
|
||||||
|
for _,m in ipairs(aClass.__metamethods) do
|
||||||
|
aClass[m]= _createLookupMetamethod(aClass, m)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _setDefaultInitializeMethod(aClass, super)
|
||||||
|
aClass.initialize = function(instance, ...)
|
||||||
|
return super.initialize(instance, ...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _includeMixin(aClass, mixin)
|
||||||
|
assert(type(mixin)=='table', "mixin must be a table")
|
||||||
|
for name,method in pairs(mixin) do
|
||||||
|
if name ~= "included" and name ~= "static" then aClass[name] = method end
|
||||||
|
end
|
||||||
|
if mixin.static then
|
||||||
|
for name,method in pairs(mixin.static) do
|
||||||
|
aClass.static[name] = method
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if type(mixin.included)=="function" then mixin:included(aClass) end
|
||||||
|
aClass.__mixins[mixin] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
local Object = _createClass("Object", nil)
|
||||||
|
|
||||||
|
Object.static.__metamethods = { '__add', '__band', '__bor', '__bxor', '__bnot', '__call', '__concat',
|
||||||
|
'__div', '__eq', '__ipairs', '__idiv', '__le', '__len', '__lt', '__mod',
|
||||||
|
'__mul', '__pairs', '__pow', '__shl', '__shr', '__sub', '__tostring', '__unm' }
|
||||||
|
|
||||||
|
function Object.static:allocate()
|
||||||
|
assert(type(self) == 'table', "Make sure that you are using 'Class:allocate' instead of 'Class.allocate'")
|
||||||
|
return setmetatable({ class = self }, self.__instanceDict)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Object.static:new(...)
|
||||||
|
local instance = self:allocate()
|
||||||
|
instance:initialize(...)
|
||||||
|
return instance
|
||||||
|
end
|
||||||
|
|
||||||
|
function Object.static:subclass(name)
|
||||||
|
assert(type(self) == 'table', "Make sure that you are using 'Class:subclass' instead of 'Class.subclass'")
|
||||||
|
assert(type(name) == "string", "You must provide a name(string) for your class")
|
||||||
|
|
||||||
|
local subclass = _createClass(name, self)
|
||||||
|
_setClassMetamethods(subclass)
|
||||||
|
_setDefaultInitializeMethod(subclass, self)
|
||||||
|
self.subclasses[subclass] = true
|
||||||
|
self:subclassed(subclass)
|
||||||
|
|
||||||
|
return subclass
|
||||||
|
end
|
||||||
|
|
||||||
|
function Object.static:subclassed(other) end
|
||||||
|
|
||||||
|
function Object.static:isSubclassOf(other)
|
||||||
|
return type(other) == 'table' and
|
||||||
|
type(self) == 'table' and
|
||||||
|
type(self.super) == 'table' and
|
||||||
|
( self.super == other or
|
||||||
|
type(self.super.isSubclassOf) == 'function' and
|
||||||
|
self.super:isSubclassOf(other)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Object.static:include( ... )
|
||||||
|
assert(type(self) == 'table', "Make sure you that you are using 'Class:include' instead of 'Class.include'")
|
||||||
|
for _,mixin in ipairs({...}) do _includeMixin(self, mixin) end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function Object.static:includes(mixin)
|
||||||
|
return type(mixin) == 'table' and
|
||||||
|
type(self) == 'table' and
|
||||||
|
type(self.__mixins) == 'table' and
|
||||||
|
( self.__mixins[mixin] or
|
||||||
|
type(self.super) == 'table' and
|
||||||
|
type(self.super.includes) == 'function' and
|
||||||
|
self.super:includes(mixin)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Object:initialize() end
|
||||||
|
|
||||||
|
function Object:__tostring() return "instance of " .. tostring(self.class) end
|
||||||
|
|
||||||
|
function Object:isInstanceOf(aClass)
|
||||||
|
return type(self) == 'table' and
|
||||||
|
type(self.class) == 'table' and
|
||||||
|
type(aClass) == 'table' and
|
||||||
|
( aClass == self.class or
|
||||||
|
type(aClass.isSubclassOf) == 'function' and
|
||||||
|
self.class:isSubclassOf(aClass)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function middleclass.class(name, super, ...)
|
||||||
|
super = super or Object
|
||||||
|
return super:subclass(name, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
middleclass.Object = Object
|
||||||
|
|
||||||
|
setmetatable(middleclass, { __call = function(_, ...) return middleclass.class(...) end })
|
||||||
|
|
||||||
|
return middleclass
|
10
pop/skins/blacknwhite.lua
Normal file
10
pop/skins/blacknwhite.lua
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
local skin = {}
|
||||||
|
|
||||||
|
skin.style = {
|
||||||
|
background = {255,255,255,1}, -- color table, image, or false
|
||||||
|
foreground = {0,0,0,1}, -- color table
|
||||||
|
borderSize = 2, -- integer (minimum 0)
|
||||||
|
borderStyle = {255,255,255,1} -- color table, image, or false
|
||||||
|
}
|
||||||
|
|
||||||
|
return skin
|
10
pop/skins/clear.lua
Normal file
10
pop/skins/clear.lua
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
local skin = {}
|
||||||
|
|
||||||
|
skin.style = {
|
||||||
|
background = false, -- color table, image, or false
|
||||||
|
foreground = {0,0,0,1}, -- color table
|
||||||
|
borderSize = 0, -- integer (minimum 0)
|
||||||
|
borderStyle = false -- color table, image, or false
|
||||||
|
}
|
||||||
|
|
||||||
|
return skin
|
Loading…
Reference in New Issue
Block a user