mirror of
https://github.com/TangentFoxy/Pop.Box.git
synced 2024-12-15 12:44:20 +00:00
BUGGED AND BROKEN! :D
This commit is contained in:
parent
acf3972401
commit
f6ffea1e02
BIN
demo/button.9.png
Normal file
BIN
demo/button.9.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
@ -1,5 +1,5 @@
|
|||||||
local lg = love.graphics
|
local lg = love.graphics
|
||||||
local pop, inspect
|
local pop, inspect, patchy
|
||||||
|
|
||||||
local debugDraw = false
|
local debugDraw = false
|
||||||
local videoFile = lg.newVideo("test.ogv") -- so we can loop playback
|
local videoFile = lg.newVideo("test.ogv") -- so we can loop playback
|
||||||
@ -9,6 +9,7 @@ function love.load()
|
|||||||
|
|
||||||
inspect = require "debug-lib/inspect"
|
inspect = require "debug-lib/inspect"
|
||||||
pop = require "pop"
|
pop = require "pop"
|
||||||
|
patchy = require "pop.third-party.patchy"
|
||||||
---[[
|
---[[
|
||||||
local c = pop.box():align("center", "center"):setSize(300, 300)
|
local c = pop.box():align("center", "center"):setSize(300, 300)
|
||||||
pop.box(c, {255, 0, 0, 255}):setSize(100, 50)
|
pop.box(c, {255, 0, 0, 255}):setSize(100, 50)
|
||||||
@ -58,7 +59,7 @@ function love.load()
|
|||||||
print(b.data.horizontal, b.data.vertical)
|
print(b.data.horizontal, b.data.vertical)
|
||||||
print(c.data.horizontal, c.data.vertical)
|
print(c.data.horizontal, c.data.vertical)
|
||||||
|
|
||||||
local window = pop.window():align("center", "center"):setTitle("Welcome! This title is far too big!")
|
local window = pop.window():align("center", "center"):setTitle("Welcome! This title is far too big!"):resize(200)
|
||||||
|
|
||||||
pop.window():setClose(false):setClose(true)
|
pop.window():setClose(false):setClose(true)
|
||||||
|
|
||||||
@ -74,6 +75,8 @@ function love.load()
|
|||||||
end
|
end
|
||||||
print(all.__class.__name)
|
print(all.__class.__name)
|
||||||
--]]
|
--]]
|
||||||
|
|
||||||
|
button = patchy.load("button.9.png")
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.update(dt)
|
function love.update(dt)
|
||||||
@ -88,6 +91,8 @@ end
|
|||||||
function love.draw()
|
function love.draw()
|
||||||
pop.draw()
|
pop.draw()
|
||||||
|
|
||||||
|
button:draw(50, 50, 150, 50)
|
||||||
|
|
||||||
if debugDraw then
|
if debugDraw then
|
||||||
pop.debugDraw()
|
pop.debugDraw()
|
||||||
end
|
end
|
||||||
|
@ -75,10 +75,34 @@ do
|
|||||||
if background == nil then
|
if background == nil then
|
||||||
background = false
|
background = false
|
||||||
end
|
end
|
||||||
_class_0.__parent.__init(self, parent)
|
if type(background) == "table" then
|
||||||
|
for k, v in pairs(background) do
|
||||||
|
if type(k) ~= "number" then
|
||||||
|
_class_0.__parent.__init(self, parent, background)
|
||||||
|
if not background.w then
|
||||||
self.data.w = 20
|
self.data.w = 20
|
||||||
|
end
|
||||||
|
if not background.h then
|
||||||
self.data.h = 20
|
self.data.h = 20
|
||||||
|
end
|
||||||
|
if self.data.background == nil then
|
||||||
|
self.data.background = false
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
_class_0.__parent.__init(self, parent)
|
||||||
|
if not self.data.w then
|
||||||
|
self.data.w = 20
|
||||||
|
end
|
||||||
|
if not self.data.h then
|
||||||
|
self.data.h = 20
|
||||||
|
end
|
||||||
|
if not self.data.background then
|
||||||
self.data.background = background
|
self.data.background = background
|
||||||
|
end
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
__base = _base_0,
|
__base = _base_0,
|
||||||
__name = "box",
|
__name = "box",
|
||||||
|
@ -261,8 +261,8 @@ do
|
|||||||
}
|
}
|
||||||
_base_0.__index = _base_0
|
_base_0.__index = _base_0
|
||||||
_class_0 = setmetatable({
|
_class_0 = setmetatable({
|
||||||
__init = function(self, parent)
|
__init = function(self, parent, data)
|
||||||
self.data = {
|
local default = {
|
||||||
parent = parent,
|
parent = parent,
|
||||||
child = { },
|
child = { },
|
||||||
w = 0,
|
w = 0,
|
||||||
@ -276,9 +276,19 @@ do
|
|||||||
update = true,
|
update = true,
|
||||||
move = true
|
move = true
|
||||||
}
|
}
|
||||||
if parent then
|
if type(data) == "table" then
|
||||||
self.data.x = parent.data.x
|
self.data = data
|
||||||
self.data.y = parent.data.y
|
for k, v in pairs(default) do
|
||||||
|
if type(self.data[k]) == "nil" then
|
||||||
|
self.data[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.data = default
|
||||||
|
end
|
||||||
|
if self.data.parent then
|
||||||
|
self.data.x = self.data.parent.data.x
|
||||||
|
self.data.y = self.data.parent.data.y
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
__base = _base_0,
|
__base = _base_0,
|
||||||
|
@ -109,10 +109,22 @@ do
|
|||||||
255
|
255
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
if type(text) == "table" then
|
||||||
|
_class_0.__parent.__init(self, parent, text)
|
||||||
|
else
|
||||||
_class_0.__parent.__init(self, parent)
|
_class_0.__parent.__init(self, parent)
|
||||||
|
end
|
||||||
|
if not self.data.font then
|
||||||
self.data.font = graphics.newFont(14)
|
self.data.font = graphics.newFont(14)
|
||||||
self:setText(text)
|
end
|
||||||
|
if not self.data.color then
|
||||||
self.data.color = color
|
self.data.color = color
|
||||||
|
end
|
||||||
|
if type(text) == "string" then
|
||||||
|
return self:setText(text)
|
||||||
|
else
|
||||||
|
return self:setSize()
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
__base = _base_0,
|
__base = _base_0,
|
||||||
__name = "text",
|
__name = "text",
|
||||||
|
530
demo/pop/third-party/patchy.lua
vendored
Normal file
530
demo/pop/third-party/patchy.lua
vendored
Normal file
@ -0,0 +1,530 @@
|
|||||||
|
local nine = {
|
||||||
|
_VERSION = 'patchy.lua v2.0.0',
|
||||||
|
_DESCRIPTION = 'Simple 9patch library for LÖVE',
|
||||||
|
_URL = 'https://github.com/excessive/patchy/tree/master/patchy.lua',
|
||||||
|
_LICENSE = [[
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Pablo Mayobre, Colby Klein, Landon Manning
|
||||||
|
|
||||||
|
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 vertical(state, x, w, sx, row, first)
|
||||||
|
local function add(state, x, y, w, h, sx, sy, row, col)
|
||||||
|
state.areas[#state.areas + 1] = {
|
||||||
|
x = x, -- start x
|
||||||
|
y = y, -- start y
|
||||||
|
w = w, -- end x
|
||||||
|
h = h, -- end y
|
||||||
|
sx = sx, -- scale on x (bool)
|
||||||
|
sy = sy, -- scale on y (bool)
|
||||||
|
row = row, -- row number
|
||||||
|
col = col, -- col number
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local scale_y = state.scale_y
|
||||||
|
local current_pixel = 0
|
||||||
|
local col = 0
|
||||||
|
|
||||||
|
for i=1, #scale_y do
|
||||||
|
if scale_y[i].y > current_pixel then
|
||||||
|
col = col + 1
|
||||||
|
|
||||||
|
add(state, x, current_pixel, w, scale_y[i].y - current_pixel, sx, false, row, col)
|
||||||
|
|
||||||
|
if first then
|
||||||
|
state.static.y = state.static.y + scale_y[i].y - current_pixel
|
||||||
|
end
|
||||||
|
|
||||||
|
current_pixel = scale_y[i].y
|
||||||
|
end
|
||||||
|
|
||||||
|
if scale_y[i].y == current_pixel then
|
||||||
|
col = col + 1
|
||||||
|
|
||||||
|
add(state, x, scale_y[i].y, w, scale_y[i].h, sx, true, row, col)
|
||||||
|
|
||||||
|
current_pixel = scale_y[i].y + scale_y[i].h
|
||||||
|
else
|
||||||
|
error("The start of the vertical line "..i.." comes before another line finishes", 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if current_pixel < state.dimensions.h then
|
||||||
|
col = col + 1
|
||||||
|
|
||||||
|
add(state, x, current_pixel, w, state.dimensions.h - current_pixel, sx, false, row, col)
|
||||||
|
|
||||||
|
if first then
|
||||||
|
state.static.y = state.static.y + state.dimensions.h - current_pixel
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function horizontal(state)
|
||||||
|
local scale_x = state.scale_x
|
||||||
|
local current_pixel = 0
|
||||||
|
local row = 0
|
||||||
|
|
||||||
|
for i=1, #scale_x do
|
||||||
|
-- If scale area is after current pixel
|
||||||
|
if scale_x[i].x > current_pixel then
|
||||||
|
row = row + 1
|
||||||
|
|
||||||
|
-- If first scale area
|
||||||
|
if i == 1 then
|
||||||
|
vertical(state, current_pixel, scale_x[i].x - current_pixel, false, row, true)
|
||||||
|
else
|
||||||
|
vertical(state, current_pixel, scale_x[i].x - current_pixel, false, row)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- calculate non-scaled area
|
||||||
|
state.static.x = state.static.x + scale_x[i].x - current_pixel
|
||||||
|
|
||||||
|
-- set current pixel to start of scale area
|
||||||
|
current_pixel = scale_x[i].x
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If current pixel is the beginning of scale area
|
||||||
|
if scale_x[i].x == current_pixel then
|
||||||
|
row = row + 1
|
||||||
|
|
||||||
|
-- If first scale area and first scale area begins at 0 (no corner piece)
|
||||||
|
if i == 1 and row == 1 then
|
||||||
|
vertical(state, scale_x[i].x, scale_x[i].w, true, row, true)
|
||||||
|
else
|
||||||
|
vertical(state, scale_x[i].x, scale_x[i].w, true, row)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- set current pixel to end of scale area
|
||||||
|
current_pixel = scale_x[i].x + scale_x[i].w
|
||||||
|
else
|
||||||
|
error(string.format("The start of the horizontal line %d comes before another line finishes", i), 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If current pixel is less than total size of image
|
||||||
|
if current_pixel < state.dimensions.w then
|
||||||
|
row = row + 1
|
||||||
|
vertical(state, current_pixel, state.dimensions.w - current_pixel, false, row)
|
||||||
|
state.static.x = state.static.x + state.dimensions.w - current_pixel
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Content Box (border - padding)
|
||||||
|
local function get_content_box(p, x, y, w, h, preprocessed)
|
||||||
|
if not preprocessed then
|
||||||
|
x, y = (x or 0), (y or 0)
|
||||||
|
w = math.max((w or 0) - p.static.x, 0) + p.static.x
|
||||||
|
h = math.max((h or 0) - p.static.y, 0) + p.static.y
|
||||||
|
end
|
||||||
|
|
||||||
|
return x + p.pad[4], y + p.pad[1], w - p.pad[2] - p.pad[4] + p.static.x, h - p.pad[1] - p.pad[3] + p.static.y
|
||||||
|
end
|
||||||
|
-- Border Box (content + padding)
|
||||||
|
local function get_border_box(p, x, y, w, h, preprocessed)
|
||||||
|
if not preprocessed then
|
||||||
|
x, y = (x or 0), (y or 0)
|
||||||
|
w, h = (w or 0), (h or 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
x, y, w, h = x - p.pad[4], y - p.pad[1], w + p.pad[2] + p.pad[4], h + p.pad[1] + p.pad[3]
|
||||||
|
|
||||||
|
if not preprocessed then
|
||||||
|
w = math.max(w - p.static.x, 0) + p.static.x
|
||||||
|
h = math.max(h - p.static.y, 0) + p.static.x
|
||||||
|
end
|
||||||
|
return x, y, w, h
|
||||||
|
end
|
||||||
|
|
||||||
|
local function draw(p, x, y, w, h, content_box)
|
||||||
|
local skip_update = false
|
||||||
|
|
||||||
|
-- If all args match previous draw, no need to update the batch.
|
||||||
|
if p.last_args then
|
||||||
|
local ox, oy, ow, oh, ocontent_box = unpack(p.last_args)
|
||||||
|
if x == ox and y == oy and w == ow and h == oh and content_box == ocontent_box then
|
||||||
|
skip_update = true
|
||||||
|
else
|
||||||
|
p.last_args[1] = x
|
||||||
|
p.last_args[2] = y
|
||||||
|
p.last_args[3] = w
|
||||||
|
p.last_args[4] = h
|
||||||
|
p.last_args[5] = content_box
|
||||||
|
end
|
||||||
|
else
|
||||||
|
p.last_args = { x, y, w, h, content_box }
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Box Size
|
||||||
|
x, y = (x or 0), (y or 0)
|
||||||
|
w, h = (w or 0), (h or 0)
|
||||||
|
|
||||||
|
if content_box then -- Content box model
|
||||||
|
x, y, w, h = get_border_box(p, x, y, w, h, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
w = math.max(w - p.static.x, 0)
|
||||||
|
h = math.max(h - p.static.y, 0)
|
||||||
|
|
||||||
|
-- Content Box
|
||||||
|
local cx, cy, cw, ch = get_content_box(p, x, y, w, h, true)
|
||||||
|
|
||||||
|
if not skip_update then
|
||||||
|
-- Divide size by scale area
|
||||||
|
local pax, pay = x, y
|
||||||
|
local sax, say = w / p.dynamic.x, h / p.dynamic.y
|
||||||
|
|
||||||
|
local row, col = 1, 1
|
||||||
|
for i=1, #p.areas do
|
||||||
|
if p.areas[i].row > row then
|
||||||
|
row = p.areas[i].row
|
||||||
|
pax = pax + p.areas[i - 1].w * (p.areas[i - 1].sx and sax or 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
if p.areas[i].col > col then
|
||||||
|
col = p.areas[i].col
|
||||||
|
pay = pay + p.areas[i - 1].h * (p.areas[i - 1].sy and say or 1)
|
||||||
|
elseif p.areas[i].col == 1 then
|
||||||
|
col = p.areas[i].col
|
||||||
|
pay = y
|
||||||
|
end
|
||||||
|
|
||||||
|
if p.areas[i].id then
|
||||||
|
p.batch:set(p.areas[i].id, p.areas[i].quad, pax, pay, 0, p.areas[i].sx and sax or 1, p.areas[i].sy and say or 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
love.graphics.draw(p.batch)
|
||||||
|
|
||||||
|
if debug_draw then
|
||||||
|
love.graphics.setColor(255, 0, 0, 255)
|
||||||
|
love.graphics.rectangle("line", get_border_box(p, cx, cy, cw, ch)) --Fixes debug_draw drawing the box littler than how it was
|
||||||
|
love.graphics.setColor(0, 255, 0, 255)
|
||||||
|
love.graphics.rectangle("line", cx, cy, cw, ch)
|
||||||
|
love.graphics.setColor(255, 255, 255, 255)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- return content box for lazy people who don't want to call get_content_box again
|
||||||
|
return cx, cy, cw, ch
|
||||||
|
end
|
||||||
|
|
||||||
|
local function dump (state, filename, save_image)
|
||||||
|
--Dumb serialization
|
||||||
|
local str = [[local metadata = function ()
|
||||||
|
return {
|
||||||
|
type = "9patch",
|
||||||
|
areas = {]]
|
||||||
|
|
||||||
|
for _, area in ipairs(state.areas) do
|
||||||
|
str = str..[[
|
||||||
|
|
||||||
|
{
|
||||||
|
x = ]]..tostring(area.x)..[[,
|
||||||
|
y = ]]..tostring(area.y)..[[,
|
||||||
|
w = ]]..tostring(area.w)..[[,
|
||||||
|
h = ]]..tostring(area.h)..[[,
|
||||||
|
sx = ]]..tostring(area.sx)..[[,
|
||||||
|
sy = ]]..tostring(area.sy)..[[,
|
||||||
|
row = ]]..tostring(area.row)..[[,
|
||||||
|
col = ]]..tostring(area.col)..[[,
|
||||||
|
},]]
|
||||||
|
end
|
||||||
|
|
||||||
|
str = str:sub(1, -2) .. [[
|
||||||
|
|
||||||
|
},
|
||||||
|
dimensions = {w = ]] .. tostring(state.dimensions.w) .. ", h = ".. tostring(state.dimensions.h) .. [[},
|
||||||
|
dynamic = {x = ]] .. tostring(state.dynamic.x) .. ", y = " .. tostring(state.dynamic.y) .. [[},
|
||||||
|
static = {x = ]] .. tostring(state.static.x) .. ", y = ".. tostring(state.static.y) .. [[},
|
||||||
|
pad = {]]
|
||||||
|
|
||||||
|
for _, padding in ipairs(state.pad) do
|
||||||
|
str = str .. tostring(padding) .. ","
|
||||||
|
end
|
||||||
|
|
||||||
|
str = str:sub(1, -2) .. [[}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return metadata]]
|
||||||
|
|
||||||
|
--Save the data in a file
|
||||||
|
love.filesystem.write(filename or "", str or "")
|
||||||
|
|
||||||
|
--Also save the image if required
|
||||||
|
if save_image then
|
||||||
|
local filename = (filename:match("(.-)%..-$") or "image")..".png" --Maybe this should be ".9.png" ?
|
||||||
|
local data = state.image:getData()
|
||||||
|
data:encode(filename)
|
||||||
|
end
|
||||||
|
|
||||||
|
return str
|
||||||
|
end
|
||||||
|
|
||||||
|
local function postprocess(state)
|
||||||
|
if #state.areas < 1 then
|
||||||
|
error("There are no areas in this patch", 2)
|
||||||
|
else
|
||||||
|
for _, area in ipairs(state.areas) do
|
||||||
|
if area.w and area.w > 0 and area.h and area.h > 0 then
|
||||||
|
area.quad = love.graphics.newQuad(area.x, area.y, area.w, area.h, state.dimensions.w, state.dimensions.h)
|
||||||
|
area.id = state.batch:add(area.quad)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
state.draw = draw
|
||||||
|
state.get_border_box = get_border_box
|
||||||
|
state.get_content_box = get_content_box
|
||||||
|
state.dump = dump
|
||||||
|
|
||||||
|
return state
|
||||||
|
end
|
||||||
|
|
||||||
|
local function process(patch)
|
||||||
|
local image = patch.image
|
||||||
|
|
||||||
|
if not image then
|
||||||
|
error("No images for this patch", 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
local _w, _h = image:getDimensions()
|
||||||
|
|
||||||
|
local state = {
|
||||||
|
type = "9patch",
|
||||||
|
image = image,
|
||||||
|
batch = patch.batch,
|
||||||
|
pad = patch.pad,
|
||||||
|
scale_x = patch.scale_x,
|
||||||
|
scale_y = patch.scale_y,
|
||||||
|
areas = {},
|
||||||
|
static = {x = 0, y = 0},
|
||||||
|
dimensions = {w = _w, h = _h},
|
||||||
|
}
|
||||||
|
|
||||||
|
horizontal(state)
|
||||||
|
|
||||||
|
state.dynamic = {
|
||||||
|
x = state.dimensions.w - state.static.x,
|
||||||
|
y = state.dimensions.h - state.static.y,
|
||||||
|
}
|
||||||
|
|
||||||
|
state.scale_x, state.scale_y = nil, nil
|
||||||
|
|
||||||
|
return postprocess(state)
|
||||||
|
end
|
||||||
|
|
||||||
|
function nine.load(img, metadata)
|
||||||
|
-- *.9.png
|
||||||
|
if type(img) == "string" then
|
||||||
|
img = love.graphics.newImage(img)
|
||||||
|
end
|
||||||
|
|
||||||
|
local data = img:getData()
|
||||||
|
local w, h = img:getDimensions()
|
||||||
|
|
||||||
|
local aw, ah = img:getWidth()-2, img:getHeight()-2
|
||||||
|
local asset = love.image.newImageData(aw, ah)
|
||||||
|
|
||||||
|
asset:paste(data, 0, 0, 1, 1, aw, ah)
|
||||||
|
|
||||||
|
local srgb = select(3, love.window.getMode()).srgb
|
||||||
|
local image = love.graphics.newImage(asset, srgb and "srgb" or nil)
|
||||||
|
|
||||||
|
if type(metadata) == "string" then
|
||||||
|
metadata = love.filesystem.load(metadata)
|
||||||
|
if not metadata then error("Invalid metadata file passed to 'import'",2) end
|
||||||
|
metadata = metadata()
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(metadata) == "function" then
|
||||||
|
metadata = metadata()
|
||||||
|
end
|
||||||
|
|
||||||
|
if metadata and metadata.type == "9patch" then
|
||||||
|
metadata.image = image
|
||||||
|
return nine.import(image, metadata)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 9patch data
|
||||||
|
local scale_x, scale_y = {{}}, {{}}
|
||||||
|
local fill_x, fill_y = {}, {}
|
||||||
|
|
||||||
|
-- Scan horizontal rows for 9patch data
|
||||||
|
for i=0, w - 1 do
|
||||||
|
-- Top row, scale
|
||||||
|
local r, g, b, a = data:getPixel(i, 0)
|
||||||
|
|
||||||
|
-- If we are currently in a scale stream, check to see if we leave it (not black)
|
||||||
|
if scale_x[#scale_x].x then
|
||||||
|
if not scale_x[#scale_x].w and (r ~= 0 or g ~=0 or b ~= 0 or a ~= 255) then
|
||||||
|
scale_x[#scale_x].w = (i - 1) - scale_x[#scale_x].x
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- If we are not in a scale stream, check to see if we are starting one (black)
|
||||||
|
if r == 0 and g == 0 and b == 0 and a == 255 then
|
||||||
|
scale_x[#scale_x].x = i - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Bottom row, fill
|
||||||
|
local r, g, b, a = data:getPixel(i, h - 1)
|
||||||
|
|
||||||
|
-- If we are in a fill stream, check to see if we leave it (not black)
|
||||||
|
if fill_x.x then
|
||||||
|
if not fill_x.w and (r ~= 0 or g ~= 0 or b ~= 0 or a ~= 255) then
|
||||||
|
fill_x.w = (i - 1) - fill_x.x
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- If we are not in a fill stream, check to see if we are starting one (black)
|
||||||
|
if r == 0 and g == 0 and b == 0 and a == 255 then
|
||||||
|
fill_x.x = i - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- stahp
|
||||||
|
if scale_x[#scale_x].w then
|
||||||
|
scale_x[#scale_x + 1] = {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- if the last table is empty (stahp)
|
||||||
|
if not scale_x[#scale_x].x then
|
||||||
|
-- if there is only one table, no 9patch data
|
||||||
|
if #scale_x == 1 then
|
||||||
|
error("Invalid 9-patch image, it doesnt contain an horizontal line", 2)
|
||||||
|
else
|
||||||
|
scale_x[#scale_x] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- staaaaahp
|
||||||
|
if not scale_x[#scale_x].w then
|
||||||
|
scale_x[#scale_x].w = (w - 1) - scale_x[#scale_x].x
|
||||||
|
end
|
||||||
|
|
||||||
|
--same as above, but for height!
|
||||||
|
for i=0, h - 1 do
|
||||||
|
local r, g, b, a = data:getPixel(0, i)
|
||||||
|
|
||||||
|
if scale_y[#scale_y].y then
|
||||||
|
if not scale_y.h and (r ~= 0 or g ~=0 or b ~= 0 or a ~= 255) then
|
||||||
|
scale_y[#scale_y].h = (i - 1) - scale_y[#scale_y].y
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if r == 0 and g == 0 and b == 0 and a == 255 then
|
||||||
|
scale_y[#scale_y].y = i - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local r, g, b, a = data:getPixel(w - 1, i)
|
||||||
|
|
||||||
|
if fill_y.y then
|
||||||
|
if not fill_y.h and (r ~= 0 or g ~= 0 or b ~= 0 or a ~= 255) then
|
||||||
|
fill_y.h = (i - 1) - fill_y.y
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if r == 0 and g == 0 and b == 0 and a == 255 then
|
||||||
|
fill_y.y = i - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if scale_y[#scale_y].h then
|
||||||
|
scale_y[#scale_y + 1] = {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not scale_y[#scale_y].y then
|
||||||
|
if #scale_y == 1 then
|
||||||
|
error("Invalid 9-patch image, it doesnt contain a vertical line",2)
|
||||||
|
else
|
||||||
|
scale_y[#scale_y] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not scale_y[#scale_y].h then
|
||||||
|
scale_y[#scale_y].h = (h - 1) - scale_y[#scale_y].y
|
||||||
|
end
|
||||||
|
|
||||||
|
-- maaaaath
|
||||||
|
local scale_w = scale_x[#scale_x].x + scale_x[#scale_x].w - scale_x[1].x
|
||||||
|
local scale_h = scale_y[#scale_y].y + scale_y[#scale_y].h - scale_y[1].y
|
||||||
|
|
||||||
|
fill_x.w = fill_x.x and (fill_x.w and fill_x.w or (w - 1 - fill_x.x)) or scale_w
|
||||||
|
fill_y.h = fill_y.y and (fill_y.h and fill_y.h or (h - 1 - fill_y.y)) or scale_h
|
||||||
|
|
||||||
|
fill_x.x = fill_x.x and fill_x.x or scale_x[1].x
|
||||||
|
fill_y.y = fill_y.y and fill_y.y or scale_y[1].y
|
||||||
|
|
||||||
|
local pad = {
|
||||||
|
- fill_y.y + scale_y[1].y,
|
||||||
|
- (scale_x[1].x + scale_w) + (fill_x.x + fill_x.w),
|
||||||
|
- (scale_y[1].y + scale_h) + (fill_y.y + fill_y.h),
|
||||||
|
- fill_x.x + scale_x[1].x,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Dear Positive,
|
||||||
|
-- ??????????????????????????
|
||||||
|
-- Sincerely, me.
|
||||||
|
local patch = {
|
||||||
|
image = image,
|
||||||
|
batch = love.graphics.newSpriteBatch(image, (#scale_x * 2 + 1) * (#scale_y * 2 + 1)),
|
||||||
|
pad = pad,
|
||||||
|
scale_x = scale_x,
|
||||||
|
scale_y = scale_y,
|
||||||
|
}
|
||||||
|
|
||||||
|
return process(patch)
|
||||||
|
end
|
||||||
|
|
||||||
|
function nine.import (image, metadata)
|
||||||
|
if type(metadata) == "string" then
|
||||||
|
metadata = love.filesystem.load(metadata)
|
||||||
|
if not metadata then error("Invalid metadata file passed to 'import'",2) end
|
||||||
|
metadata = metadata()
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(metadata) == "function" then
|
||||||
|
metadata = metadata()
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(metadata) ~= "table" then
|
||||||
|
error("bad argument #2 to 'import' (table expected, got "..type(metadata)..")", 2)
|
||||||
|
end
|
||||||
|
-- *.9.png
|
||||||
|
if type(image) == "string" then
|
||||||
|
image = love.graphics.newImage(image)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not image or not image.type or image:type() ~= "Image" then
|
||||||
|
error("bad argument #1 to 'import' (Image expected, got "..(image.type and image:type() or type(image))..")", 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
metadata.image = image
|
||||||
|
|
||||||
|
metadata.batch = love.graphics.newSpriteBatch(image, #metadata.areas)
|
||||||
|
return postprocess(metadata)
|
||||||
|
end
|
||||||
|
|
||||||
|
return nine
|
BIN
demo/window.9.png
Normal file
BIN
demo/window.9.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
@ -75,10 +75,34 @@ do
|
|||||||
if background == nil then
|
if background == nil then
|
||||||
background = false
|
background = false
|
||||||
end
|
end
|
||||||
_class_0.__parent.__init(self, parent)
|
if type(background) == "table" then
|
||||||
|
for k, v in pairs(background) do
|
||||||
|
if type(k) ~= "number" then
|
||||||
|
_class_0.__parent.__init(self, parent, background)
|
||||||
|
if not background.w then
|
||||||
self.data.w = 20
|
self.data.w = 20
|
||||||
|
end
|
||||||
|
if not background.h then
|
||||||
self.data.h = 20
|
self.data.h = 20
|
||||||
|
end
|
||||||
|
if self.data.background == nil then
|
||||||
|
self.data.background = false
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
_class_0.__parent.__init(self, parent)
|
||||||
|
if not self.data.w then
|
||||||
|
self.data.w = 20
|
||||||
|
end
|
||||||
|
if not self.data.h then
|
||||||
|
self.data.h = 20
|
||||||
|
end
|
||||||
|
if not self.data.background then
|
||||||
self.data.background = background
|
self.data.background = background
|
||||||
|
end
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
__base = _base_0,
|
__base = _base_0,
|
||||||
__name = "box",
|
__name = "box",
|
||||||
|
@ -261,8 +261,8 @@ do
|
|||||||
}
|
}
|
||||||
_base_0.__index = _base_0
|
_base_0.__index = _base_0
|
||||||
_class_0 = setmetatable({
|
_class_0 = setmetatable({
|
||||||
__init = function(self, parent)
|
__init = function(self, parent, data)
|
||||||
self.data = {
|
local default = {
|
||||||
parent = parent,
|
parent = parent,
|
||||||
child = { },
|
child = { },
|
||||||
w = 0,
|
w = 0,
|
||||||
@ -276,9 +276,19 @@ do
|
|||||||
update = true,
|
update = true,
|
||||||
move = true
|
move = true
|
||||||
}
|
}
|
||||||
if parent then
|
if type(data) == "table" then
|
||||||
self.data.x = parent.data.x
|
self.data = data
|
||||||
self.data.y = parent.data.y
|
for k, v in pairs(default) do
|
||||||
|
if type(self.data[k]) == "nil" then
|
||||||
|
self.data[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.data = default
|
||||||
|
end
|
||||||
|
if self.data.parent then
|
||||||
|
self.data.x = self.data.parent.data.x
|
||||||
|
self.data.y = self.data.parent.data.y
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
__base = _base_0,
|
__base = _base_0,
|
||||||
|
@ -109,10 +109,22 @@ do
|
|||||||
255
|
255
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
if type(text) == "table" then
|
||||||
|
_class_0.__parent.__init(self, parent, text)
|
||||||
|
else
|
||||||
_class_0.__parent.__init(self, parent)
|
_class_0.__parent.__init(self, parent)
|
||||||
|
end
|
||||||
|
if not self.data.font then
|
||||||
self.data.font = graphics.newFont(14)
|
self.data.font = graphics.newFont(14)
|
||||||
self:setText(text)
|
end
|
||||||
|
if not self.data.color then
|
||||||
self.data.color = color
|
self.data.color = color
|
||||||
|
end
|
||||||
|
if type(text) == "string" then
|
||||||
|
return self:setText(text)
|
||||||
|
else
|
||||||
|
return self:setSize()
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
__base = _base_0,
|
__base = _base_0,
|
||||||
__name = "text",
|
__name = "text",
|
||||||
|
530
lib/pop/third-party/patchy.lua
vendored
Normal file
530
lib/pop/third-party/patchy.lua
vendored
Normal file
@ -0,0 +1,530 @@
|
|||||||
|
local nine = {
|
||||||
|
_VERSION = 'patchy.lua v2.0.0',
|
||||||
|
_DESCRIPTION = 'Simple 9patch library for LÖVE',
|
||||||
|
_URL = 'https://github.com/excessive/patchy/tree/master/patchy.lua',
|
||||||
|
_LICENSE = [[
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Pablo Mayobre, Colby Klein, Landon Manning
|
||||||
|
|
||||||
|
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 vertical(state, x, w, sx, row, first)
|
||||||
|
local function add(state, x, y, w, h, sx, sy, row, col)
|
||||||
|
state.areas[#state.areas + 1] = {
|
||||||
|
x = x, -- start x
|
||||||
|
y = y, -- start y
|
||||||
|
w = w, -- end x
|
||||||
|
h = h, -- end y
|
||||||
|
sx = sx, -- scale on x (bool)
|
||||||
|
sy = sy, -- scale on y (bool)
|
||||||
|
row = row, -- row number
|
||||||
|
col = col, -- col number
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local scale_y = state.scale_y
|
||||||
|
local current_pixel = 0
|
||||||
|
local col = 0
|
||||||
|
|
||||||
|
for i=1, #scale_y do
|
||||||
|
if scale_y[i].y > current_pixel then
|
||||||
|
col = col + 1
|
||||||
|
|
||||||
|
add(state, x, current_pixel, w, scale_y[i].y - current_pixel, sx, false, row, col)
|
||||||
|
|
||||||
|
if first then
|
||||||
|
state.static.y = state.static.y + scale_y[i].y - current_pixel
|
||||||
|
end
|
||||||
|
|
||||||
|
current_pixel = scale_y[i].y
|
||||||
|
end
|
||||||
|
|
||||||
|
if scale_y[i].y == current_pixel then
|
||||||
|
col = col + 1
|
||||||
|
|
||||||
|
add(state, x, scale_y[i].y, w, scale_y[i].h, sx, true, row, col)
|
||||||
|
|
||||||
|
current_pixel = scale_y[i].y + scale_y[i].h
|
||||||
|
else
|
||||||
|
error("The start of the vertical line "..i.." comes before another line finishes", 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if current_pixel < state.dimensions.h then
|
||||||
|
col = col + 1
|
||||||
|
|
||||||
|
add(state, x, current_pixel, w, state.dimensions.h - current_pixel, sx, false, row, col)
|
||||||
|
|
||||||
|
if first then
|
||||||
|
state.static.y = state.static.y + state.dimensions.h - current_pixel
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function horizontal(state)
|
||||||
|
local scale_x = state.scale_x
|
||||||
|
local current_pixel = 0
|
||||||
|
local row = 0
|
||||||
|
|
||||||
|
for i=1, #scale_x do
|
||||||
|
-- If scale area is after current pixel
|
||||||
|
if scale_x[i].x > current_pixel then
|
||||||
|
row = row + 1
|
||||||
|
|
||||||
|
-- If first scale area
|
||||||
|
if i == 1 then
|
||||||
|
vertical(state, current_pixel, scale_x[i].x - current_pixel, false, row, true)
|
||||||
|
else
|
||||||
|
vertical(state, current_pixel, scale_x[i].x - current_pixel, false, row)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- calculate non-scaled area
|
||||||
|
state.static.x = state.static.x + scale_x[i].x - current_pixel
|
||||||
|
|
||||||
|
-- set current pixel to start of scale area
|
||||||
|
current_pixel = scale_x[i].x
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If current pixel is the beginning of scale area
|
||||||
|
if scale_x[i].x == current_pixel then
|
||||||
|
row = row + 1
|
||||||
|
|
||||||
|
-- If first scale area and first scale area begins at 0 (no corner piece)
|
||||||
|
if i == 1 and row == 1 then
|
||||||
|
vertical(state, scale_x[i].x, scale_x[i].w, true, row, true)
|
||||||
|
else
|
||||||
|
vertical(state, scale_x[i].x, scale_x[i].w, true, row)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- set current pixel to end of scale area
|
||||||
|
current_pixel = scale_x[i].x + scale_x[i].w
|
||||||
|
else
|
||||||
|
error(string.format("The start of the horizontal line %d comes before another line finishes", i), 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If current pixel is less than total size of image
|
||||||
|
if current_pixel < state.dimensions.w then
|
||||||
|
row = row + 1
|
||||||
|
vertical(state, current_pixel, state.dimensions.w - current_pixel, false, row)
|
||||||
|
state.static.x = state.static.x + state.dimensions.w - current_pixel
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Content Box (border - padding)
|
||||||
|
local function get_content_box(p, x, y, w, h, preprocessed)
|
||||||
|
if not preprocessed then
|
||||||
|
x, y = (x or 0), (y or 0)
|
||||||
|
w = math.max((w or 0) - p.static.x, 0) + p.static.x
|
||||||
|
h = math.max((h or 0) - p.static.y, 0) + p.static.y
|
||||||
|
end
|
||||||
|
|
||||||
|
return x + p.pad[4], y + p.pad[1], w - p.pad[2] - p.pad[4] + p.static.x, h - p.pad[1] - p.pad[3] + p.static.y
|
||||||
|
end
|
||||||
|
-- Border Box (content + padding)
|
||||||
|
local function get_border_box(p, x, y, w, h, preprocessed)
|
||||||
|
if not preprocessed then
|
||||||
|
x, y = (x or 0), (y or 0)
|
||||||
|
w, h = (w or 0), (h or 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
x, y, w, h = x - p.pad[4], y - p.pad[1], w + p.pad[2] + p.pad[4], h + p.pad[1] + p.pad[3]
|
||||||
|
|
||||||
|
if not preprocessed then
|
||||||
|
w = math.max(w - p.static.x, 0) + p.static.x
|
||||||
|
h = math.max(h - p.static.y, 0) + p.static.x
|
||||||
|
end
|
||||||
|
return x, y, w, h
|
||||||
|
end
|
||||||
|
|
||||||
|
local function draw(p, x, y, w, h, content_box)
|
||||||
|
local skip_update = false
|
||||||
|
|
||||||
|
-- If all args match previous draw, no need to update the batch.
|
||||||
|
if p.last_args then
|
||||||
|
local ox, oy, ow, oh, ocontent_box = unpack(p.last_args)
|
||||||
|
if x == ox and y == oy and w == ow and h == oh and content_box == ocontent_box then
|
||||||
|
skip_update = true
|
||||||
|
else
|
||||||
|
p.last_args[1] = x
|
||||||
|
p.last_args[2] = y
|
||||||
|
p.last_args[3] = w
|
||||||
|
p.last_args[4] = h
|
||||||
|
p.last_args[5] = content_box
|
||||||
|
end
|
||||||
|
else
|
||||||
|
p.last_args = { x, y, w, h, content_box }
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Box Size
|
||||||
|
x, y = (x or 0), (y or 0)
|
||||||
|
w, h = (w or 0), (h or 0)
|
||||||
|
|
||||||
|
if content_box then -- Content box model
|
||||||
|
x, y, w, h = get_border_box(p, x, y, w, h, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
w = math.max(w - p.static.x, 0)
|
||||||
|
h = math.max(h - p.static.y, 0)
|
||||||
|
|
||||||
|
-- Content Box
|
||||||
|
local cx, cy, cw, ch = get_content_box(p, x, y, w, h, true)
|
||||||
|
|
||||||
|
if not skip_update then
|
||||||
|
-- Divide size by scale area
|
||||||
|
local pax, pay = x, y
|
||||||
|
local sax, say = w / p.dynamic.x, h / p.dynamic.y
|
||||||
|
|
||||||
|
local row, col = 1, 1
|
||||||
|
for i=1, #p.areas do
|
||||||
|
if p.areas[i].row > row then
|
||||||
|
row = p.areas[i].row
|
||||||
|
pax = pax + p.areas[i - 1].w * (p.areas[i - 1].sx and sax or 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
if p.areas[i].col > col then
|
||||||
|
col = p.areas[i].col
|
||||||
|
pay = pay + p.areas[i - 1].h * (p.areas[i - 1].sy and say or 1)
|
||||||
|
elseif p.areas[i].col == 1 then
|
||||||
|
col = p.areas[i].col
|
||||||
|
pay = y
|
||||||
|
end
|
||||||
|
|
||||||
|
if p.areas[i].id then
|
||||||
|
p.batch:set(p.areas[i].id, p.areas[i].quad, pax, pay, 0, p.areas[i].sx and sax or 1, p.areas[i].sy and say or 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
love.graphics.draw(p.batch)
|
||||||
|
|
||||||
|
if debug_draw then
|
||||||
|
love.graphics.setColor(255, 0, 0, 255)
|
||||||
|
love.graphics.rectangle("line", get_border_box(p, cx, cy, cw, ch)) --Fixes debug_draw drawing the box littler than how it was
|
||||||
|
love.graphics.setColor(0, 255, 0, 255)
|
||||||
|
love.graphics.rectangle("line", cx, cy, cw, ch)
|
||||||
|
love.graphics.setColor(255, 255, 255, 255)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- return content box for lazy people who don't want to call get_content_box again
|
||||||
|
return cx, cy, cw, ch
|
||||||
|
end
|
||||||
|
|
||||||
|
local function dump (state, filename, save_image)
|
||||||
|
--Dumb serialization
|
||||||
|
local str = [[local metadata = function ()
|
||||||
|
return {
|
||||||
|
type = "9patch",
|
||||||
|
areas = {]]
|
||||||
|
|
||||||
|
for _, area in ipairs(state.areas) do
|
||||||
|
str = str..[[
|
||||||
|
|
||||||
|
{
|
||||||
|
x = ]]..tostring(area.x)..[[,
|
||||||
|
y = ]]..tostring(area.y)..[[,
|
||||||
|
w = ]]..tostring(area.w)..[[,
|
||||||
|
h = ]]..tostring(area.h)..[[,
|
||||||
|
sx = ]]..tostring(area.sx)..[[,
|
||||||
|
sy = ]]..tostring(area.sy)..[[,
|
||||||
|
row = ]]..tostring(area.row)..[[,
|
||||||
|
col = ]]..tostring(area.col)..[[,
|
||||||
|
},]]
|
||||||
|
end
|
||||||
|
|
||||||
|
str = str:sub(1, -2) .. [[
|
||||||
|
|
||||||
|
},
|
||||||
|
dimensions = {w = ]] .. tostring(state.dimensions.w) .. ", h = ".. tostring(state.dimensions.h) .. [[},
|
||||||
|
dynamic = {x = ]] .. tostring(state.dynamic.x) .. ", y = " .. tostring(state.dynamic.y) .. [[},
|
||||||
|
static = {x = ]] .. tostring(state.static.x) .. ", y = ".. tostring(state.static.y) .. [[},
|
||||||
|
pad = {]]
|
||||||
|
|
||||||
|
for _, padding in ipairs(state.pad) do
|
||||||
|
str = str .. tostring(padding) .. ","
|
||||||
|
end
|
||||||
|
|
||||||
|
str = str:sub(1, -2) .. [[}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return metadata]]
|
||||||
|
|
||||||
|
--Save the data in a file
|
||||||
|
love.filesystem.write(filename or "", str or "")
|
||||||
|
|
||||||
|
--Also save the image if required
|
||||||
|
if save_image then
|
||||||
|
local filename = (filename:match("(.-)%..-$") or "image")..".png" --Maybe this should be ".9.png" ?
|
||||||
|
local data = state.image:getData()
|
||||||
|
data:encode(filename)
|
||||||
|
end
|
||||||
|
|
||||||
|
return str
|
||||||
|
end
|
||||||
|
|
||||||
|
local function postprocess(state)
|
||||||
|
if #state.areas < 1 then
|
||||||
|
error("There are no areas in this patch", 2)
|
||||||
|
else
|
||||||
|
for _, area in ipairs(state.areas) do
|
||||||
|
if area.w and area.w > 0 and area.h and area.h > 0 then
|
||||||
|
area.quad = love.graphics.newQuad(area.x, area.y, area.w, area.h, state.dimensions.w, state.dimensions.h)
|
||||||
|
area.id = state.batch:add(area.quad)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
state.draw = draw
|
||||||
|
state.get_border_box = get_border_box
|
||||||
|
state.get_content_box = get_content_box
|
||||||
|
state.dump = dump
|
||||||
|
|
||||||
|
return state
|
||||||
|
end
|
||||||
|
|
||||||
|
local function process(patch)
|
||||||
|
local image = patch.image
|
||||||
|
|
||||||
|
if not image then
|
||||||
|
error("No images for this patch", 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
local _w, _h = image:getDimensions()
|
||||||
|
|
||||||
|
local state = {
|
||||||
|
type = "9patch",
|
||||||
|
image = image,
|
||||||
|
batch = patch.batch,
|
||||||
|
pad = patch.pad,
|
||||||
|
scale_x = patch.scale_x,
|
||||||
|
scale_y = patch.scale_y,
|
||||||
|
areas = {},
|
||||||
|
static = {x = 0, y = 0},
|
||||||
|
dimensions = {w = _w, h = _h},
|
||||||
|
}
|
||||||
|
|
||||||
|
horizontal(state)
|
||||||
|
|
||||||
|
state.dynamic = {
|
||||||
|
x = state.dimensions.w - state.static.x,
|
||||||
|
y = state.dimensions.h - state.static.y,
|
||||||
|
}
|
||||||
|
|
||||||
|
state.scale_x, state.scale_y = nil, nil
|
||||||
|
|
||||||
|
return postprocess(state)
|
||||||
|
end
|
||||||
|
|
||||||
|
function nine.load(img, metadata)
|
||||||
|
-- *.9.png
|
||||||
|
if type(img) == "string" then
|
||||||
|
img = love.graphics.newImage(img)
|
||||||
|
end
|
||||||
|
|
||||||
|
local data = img:getData()
|
||||||
|
local w, h = img:getDimensions()
|
||||||
|
|
||||||
|
local aw, ah = img:getWidth()-2, img:getHeight()-2
|
||||||
|
local asset = love.image.newImageData(aw, ah)
|
||||||
|
|
||||||
|
asset:paste(data, 0, 0, 1, 1, aw, ah)
|
||||||
|
|
||||||
|
local srgb = select(3, love.window.getMode()).srgb
|
||||||
|
local image = love.graphics.newImage(asset, srgb and "srgb" or nil)
|
||||||
|
|
||||||
|
if type(metadata) == "string" then
|
||||||
|
metadata = love.filesystem.load(metadata)
|
||||||
|
if not metadata then error("Invalid metadata file passed to 'import'",2) end
|
||||||
|
metadata = metadata()
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(metadata) == "function" then
|
||||||
|
metadata = metadata()
|
||||||
|
end
|
||||||
|
|
||||||
|
if metadata and metadata.type == "9patch" then
|
||||||
|
metadata.image = image
|
||||||
|
return nine.import(image, metadata)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 9patch data
|
||||||
|
local scale_x, scale_y = {{}}, {{}}
|
||||||
|
local fill_x, fill_y = {}, {}
|
||||||
|
|
||||||
|
-- Scan horizontal rows for 9patch data
|
||||||
|
for i=0, w - 1 do
|
||||||
|
-- Top row, scale
|
||||||
|
local r, g, b, a = data:getPixel(i, 0)
|
||||||
|
|
||||||
|
-- If we are currently in a scale stream, check to see if we leave it (not black)
|
||||||
|
if scale_x[#scale_x].x then
|
||||||
|
if not scale_x[#scale_x].w and (r ~= 0 or g ~=0 or b ~= 0 or a ~= 255) then
|
||||||
|
scale_x[#scale_x].w = (i - 1) - scale_x[#scale_x].x
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- If we are not in a scale stream, check to see if we are starting one (black)
|
||||||
|
if r == 0 and g == 0 and b == 0 and a == 255 then
|
||||||
|
scale_x[#scale_x].x = i - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Bottom row, fill
|
||||||
|
local r, g, b, a = data:getPixel(i, h - 1)
|
||||||
|
|
||||||
|
-- If we are in a fill stream, check to see if we leave it (not black)
|
||||||
|
if fill_x.x then
|
||||||
|
if not fill_x.w and (r ~= 0 or g ~= 0 or b ~= 0 or a ~= 255) then
|
||||||
|
fill_x.w = (i - 1) - fill_x.x
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- If we are not in a fill stream, check to see if we are starting one (black)
|
||||||
|
if r == 0 and g == 0 and b == 0 and a == 255 then
|
||||||
|
fill_x.x = i - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- stahp
|
||||||
|
if scale_x[#scale_x].w then
|
||||||
|
scale_x[#scale_x + 1] = {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- if the last table is empty (stahp)
|
||||||
|
if not scale_x[#scale_x].x then
|
||||||
|
-- if there is only one table, no 9patch data
|
||||||
|
if #scale_x == 1 then
|
||||||
|
error("Invalid 9-patch image, it doesnt contain an horizontal line", 2)
|
||||||
|
else
|
||||||
|
scale_x[#scale_x] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- staaaaahp
|
||||||
|
if not scale_x[#scale_x].w then
|
||||||
|
scale_x[#scale_x].w = (w - 1) - scale_x[#scale_x].x
|
||||||
|
end
|
||||||
|
|
||||||
|
--same as above, but for height!
|
||||||
|
for i=0, h - 1 do
|
||||||
|
local r, g, b, a = data:getPixel(0, i)
|
||||||
|
|
||||||
|
if scale_y[#scale_y].y then
|
||||||
|
if not scale_y.h and (r ~= 0 or g ~=0 or b ~= 0 or a ~= 255) then
|
||||||
|
scale_y[#scale_y].h = (i - 1) - scale_y[#scale_y].y
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if r == 0 and g == 0 and b == 0 and a == 255 then
|
||||||
|
scale_y[#scale_y].y = i - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local r, g, b, a = data:getPixel(w - 1, i)
|
||||||
|
|
||||||
|
if fill_y.y then
|
||||||
|
if not fill_y.h and (r ~= 0 or g ~= 0 or b ~= 0 or a ~= 255) then
|
||||||
|
fill_y.h = (i - 1) - fill_y.y
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if r == 0 and g == 0 and b == 0 and a == 255 then
|
||||||
|
fill_y.y = i - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if scale_y[#scale_y].h then
|
||||||
|
scale_y[#scale_y + 1] = {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not scale_y[#scale_y].y then
|
||||||
|
if #scale_y == 1 then
|
||||||
|
error("Invalid 9-patch image, it doesnt contain a vertical line",2)
|
||||||
|
else
|
||||||
|
scale_y[#scale_y] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not scale_y[#scale_y].h then
|
||||||
|
scale_y[#scale_y].h = (h - 1) - scale_y[#scale_y].y
|
||||||
|
end
|
||||||
|
|
||||||
|
-- maaaaath
|
||||||
|
local scale_w = scale_x[#scale_x].x + scale_x[#scale_x].w - scale_x[1].x
|
||||||
|
local scale_h = scale_y[#scale_y].y + scale_y[#scale_y].h - scale_y[1].y
|
||||||
|
|
||||||
|
fill_x.w = fill_x.x and (fill_x.w and fill_x.w or (w - 1 - fill_x.x)) or scale_w
|
||||||
|
fill_y.h = fill_y.y and (fill_y.h and fill_y.h or (h - 1 - fill_y.y)) or scale_h
|
||||||
|
|
||||||
|
fill_x.x = fill_x.x and fill_x.x or scale_x[1].x
|
||||||
|
fill_y.y = fill_y.y and fill_y.y or scale_y[1].y
|
||||||
|
|
||||||
|
local pad = {
|
||||||
|
- fill_y.y + scale_y[1].y,
|
||||||
|
- (scale_x[1].x + scale_w) + (fill_x.x + fill_x.w),
|
||||||
|
- (scale_y[1].y + scale_h) + (fill_y.y + fill_y.h),
|
||||||
|
- fill_x.x + scale_x[1].x,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Dear Positive,
|
||||||
|
-- ??????????????????????????
|
||||||
|
-- Sincerely, me.
|
||||||
|
local patch = {
|
||||||
|
image = image,
|
||||||
|
batch = love.graphics.newSpriteBatch(image, (#scale_x * 2 + 1) * (#scale_y * 2 + 1)),
|
||||||
|
pad = pad,
|
||||||
|
scale_x = scale_x,
|
||||||
|
scale_y = scale_y,
|
||||||
|
}
|
||||||
|
|
||||||
|
return process(patch)
|
||||||
|
end
|
||||||
|
|
||||||
|
function nine.import (image, metadata)
|
||||||
|
if type(metadata) == "string" then
|
||||||
|
metadata = love.filesystem.load(metadata)
|
||||||
|
if not metadata then error("Invalid metadata file passed to 'import'",2) end
|
||||||
|
metadata = metadata()
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(metadata) == "function" then
|
||||||
|
metadata = metadata()
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(metadata) ~= "table" then
|
||||||
|
error("bad argument #2 to 'import' (table expected, got "..type(metadata)..")", 2)
|
||||||
|
end
|
||||||
|
-- *.9.png
|
||||||
|
if type(image) == "string" then
|
||||||
|
image = love.graphics.newImage(image)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not image or not image.type or image:type() ~= "Image" then
|
||||||
|
error("bad argument #1 to 'import' (Image expected, got "..(image.type and image:type() or type(image))..")", 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
metadata.image = image
|
||||||
|
|
||||||
|
metadata.batch = love.graphics.newSpriteBatch(image, #metadata.areas)
|
||||||
|
return postprocess(metadata)
|
||||||
|
end
|
||||||
|
|
||||||
|
return nine
|
@ -17,17 +17,17 @@ class box extends element
|
|||||||
@data.w = 20
|
@data.w = 20
|
||||||
if not background.h
|
if not background.h
|
||||||
@data.h = 20
|
@data.h = 20
|
||||||
if not @data.background
|
if @data.background == nil --is this correct?
|
||||||
@data.background = false
|
@data.background = false
|
||||||
return
|
return
|
||||||
--if #background < 3 or #background > 4
|
--if #background < 3 or #background > 4
|
||||||
-- super parent, background -- background has too many or too few values to be a color...though this makes NO SENSE
|
-- super parent, background -- background has too many or too few values to be a color...though this makes NO SENSE
|
||||||
-- -- would need to do the same things as above here, but it makes no sense to have this, even though it is possible, it MUST be user error
|
-- -- would need to do the same things as above here, but it makes no sense to have this, even though it is possible, it MUST be user error
|
||||||
|
else
|
||||||
super parent
|
super parent
|
||||||
if not background.w
|
if not @data.w
|
||||||
@data.w = 20
|
@data.w = 20
|
||||||
if not background.h
|
if not @data.h
|
||||||
@data.h = 20
|
@data.h = 20
|
||||||
if not @data.background
|
if not @data.background
|
||||||
@data.background = background -- we can only assume it is userdata (some LOVE object) or a color table (or the false default)
|
@data.background = background -- we can only assume it is userdata (some LOVE object) or a color table (or the false default)
|
||||||
|
Loading…
Reference in New Issue
Block a user