mirror of
https://github.com/airstruck/luigi.git
synced 2026-01-10 08:18:22 +00:00
scrap widget inheritance
This commit is contained in:
@@ -3,26 +3,22 @@ local ROOT = (...):gsub('[^.]*$', '')
|
|||||||
local Base = require(ROOT .. 'base')
|
local Base = require(ROOT .. 'base')
|
||||||
local Hooker = require(ROOT .. 'hooker')
|
local Hooker = require(ROOT .. 'hooker')
|
||||||
|
|
||||||
local Event = Base:extend { name = 'Event' }
|
local Event = Base:extend({ name = 'Event' })
|
||||||
|
|
||||||
function Event:emit (target, data, defaultAction)
|
function Event:emit (target, data, defaultAction)
|
||||||
while target do
|
local callbacks = self.registry[target]
|
||||||
local handlers = rawget(target, 'eventHandlers')
|
if not callbacks then
|
||||||
local callbacks = handlers and handlers[self.name]
|
if defaultAction then defaultAction() end
|
||||||
if callbacks then
|
return
|
||||||
local result = callbacks(data or {})
|
|
||||||
if result ~= nil then return result end
|
|
||||||
end
|
|
||||||
target = target.widgetClass
|
|
||||||
end
|
end
|
||||||
|
local result = callbacks(data or {})
|
||||||
|
if result ~= nil then return result end
|
||||||
if defaultAction then defaultAction() end
|
if defaultAction then defaultAction() end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Event:bind (target, callback)
|
function Event:bind (target, callback)
|
||||||
if not rawget(target, 'eventHandlers') then
|
local registry = self.registry
|
||||||
target.eventHandlers = {}
|
return Hooker.hook(registry, target, callback)
|
||||||
end
|
|
||||||
return Hooker.hook(target.eventHandlers, self.name, callback)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local eventNames = {
|
local eventNames = {
|
||||||
@@ -34,7 +30,10 @@ local eventNames = {
|
|||||||
local weakKeyMeta = { __mode = 'k' }
|
local weakKeyMeta = { __mode = 'k' }
|
||||||
|
|
||||||
for i, name in ipairs(eventNames) do
|
for i, name in ipairs(eventNames) do
|
||||||
Event[name] = Event:extend { name = name }
|
Event[name] = Event:extend({
|
||||||
|
name = name,
|
||||||
|
registry = setmetatable({}, weakKeyMeta),
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
function Event.injectBinders (t)
|
function Event.injectBinders (t)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ local weakValueMeta = { __mode = 'v' }
|
|||||||
|
|
||||||
function Layout:constructor (data)
|
function Layout:constructor (data)
|
||||||
self.widgets = setmetatable({}, weakValueMeta)
|
self.widgets = setmetatable({}, weakValueMeta)
|
||||||
self.root = Widget.create(self, data or {})
|
self.root = Widget(self, data or {})
|
||||||
self:setStyle()
|
self:setStyle()
|
||||||
self:setTheme()
|
self:setTheme()
|
||||||
|
|
||||||
|
|||||||
@@ -7,21 +7,15 @@ local Widget = Base:extend()
|
|||||||
|
|
||||||
Widget.isWidget = true
|
Widget.isWidget = true
|
||||||
|
|
||||||
Widget.registeredTypes = {
|
Widget.typeDecorators = {
|
||||||
sash = ROOT .. 'widget.sash',
|
sash = require(ROOT .. 'widget.sash'),
|
||||||
slider = ROOT .. 'widget.slider',
|
slider = require(ROOT .. 'widget.slider'),
|
||||||
stepper = ROOT .. 'widget.stepper',
|
stepper = require(ROOT .. 'widget.stepper'),
|
||||||
text = ROOT .. 'widget.text',
|
text = require(ROOT .. 'widget.text'),
|
||||||
}
|
}
|
||||||
|
|
||||||
function Widget.create (layout, data)
|
function Widget.register (name, decorator)
|
||||||
local path = data.type and Widget.registeredTypes[data.type]
|
Widget.typeDecorators[name] = decorator
|
||||||
|
|
||||||
if path then
|
|
||||||
return require(path)(layout, data)
|
|
||||||
end
|
|
||||||
|
|
||||||
return Widget(layout, data)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Widget:constructor (layout, data)
|
function Widget:constructor (layout, data)
|
||||||
@@ -45,6 +39,12 @@ function Widget:constructor (layout, data)
|
|||||||
local theme = widget.layout.theme
|
local theme = widget.layout.theme
|
||||||
return theme and theme:getProperty(self, property)
|
return theme and theme:getProperty(self, property)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local decorate = self.type and Widget.typeDecorators[self.type]
|
||||||
|
|
||||||
|
if decorate then
|
||||||
|
decorate(widget)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Widget:extract (data)
|
function Widget:extract (data)
|
||||||
@@ -52,7 +52,7 @@ function Widget:extract (data)
|
|||||||
-- TODO: get rid of pairs somehow
|
-- TODO: get rid of pairs somehow
|
||||||
for k, v in pairs(data) do
|
for k, v in pairs(data) do
|
||||||
if type(k) == 'number' then
|
if type(k) == 'number' then
|
||||||
children[k] = v.isWidget and v or Widget.create(self.layout, v)
|
children[k] = v.isWidget and v or Widget(self.layout, v)
|
||||||
children[k].parent = self
|
children[k].parent = self
|
||||||
else
|
else
|
||||||
self[k] = v
|
self[k] = v
|
||||||
@@ -76,7 +76,7 @@ end
|
|||||||
|
|
||||||
function Widget:addChild (data)
|
function Widget:addChild (data)
|
||||||
local layout = self.layout
|
local layout = self.layout
|
||||||
local child = Widget.create(layout, data)
|
local child = Widget(layout, data)
|
||||||
|
|
||||||
table.insert(self.children, child)
|
table.insert(self.children, child)
|
||||||
child.parent = self
|
child.parent = self
|
||||||
|
|||||||
@@ -1,33 +1,30 @@
|
|||||||
local Widget = require((...):gsub('%.[^.]*$', ''))
|
return function (self)
|
||||||
|
|
||||||
local Sash = Widget:extend()
|
self:onPressDrag(function (event)
|
||||||
|
local axis = self.parent.flow
|
||||||
|
if axis == 'x' then
|
||||||
|
dimension = 'width'
|
||||||
|
else
|
||||||
|
axis = 'y'
|
||||||
|
dimension = 'height'
|
||||||
|
end
|
||||||
|
local prevSibling = self:getPrevious()
|
||||||
|
local nextSibling = self:getNext()
|
||||||
|
local prevSize = prevSibling and prevSibling[dimension]
|
||||||
|
local nextSize = nextSibling and nextSibling[dimension]
|
||||||
|
if prevSize then
|
||||||
|
prevSibling:setDimension(dimension,
|
||||||
|
event[axis] - prevSibling:calculatePosition(axis))
|
||||||
|
end
|
||||||
|
if nextSize then
|
||||||
|
nextSibling:setDimension(dimension,
|
||||||
|
nextSibling:calculatePosition(axis) +
|
||||||
|
nextSibling[dimension] - event[axis])
|
||||||
|
end
|
||||||
|
|
||||||
Sash:onPressDrag(function (event)
|
prevSibling:reflow()
|
||||||
local self = event.target
|
nextSibling:reflow()
|
||||||
local axis = self.parent.flow
|
self:reflow()
|
||||||
if axis == 'x' then
|
end)
|
||||||
dimension = 'width'
|
|
||||||
else
|
|
||||||
axis = 'y'
|
|
||||||
dimension = 'height'
|
|
||||||
end
|
|
||||||
local prevSibling = self:getPrevious()
|
|
||||||
local nextSibling = self:getNext()
|
|
||||||
local prevSize = prevSibling and prevSibling[dimension]
|
|
||||||
local nextSize = nextSibling and nextSibling[dimension]
|
|
||||||
if prevSize then
|
|
||||||
prevSibling:setDimension(dimension,
|
|
||||||
event[axis] - prevSibling:calculatePosition(axis))
|
|
||||||
end
|
|
||||||
if nextSize then
|
|
||||||
nextSibling:setDimension(dimension,
|
|
||||||
nextSibling:calculatePosition(axis) +
|
|
||||||
nextSibling[dimension] - event[axis])
|
|
||||||
end
|
|
||||||
|
|
||||||
prevSibling:reflow()
|
end
|
||||||
nextSibling:reflow()
|
|
||||||
self:reflow()
|
|
||||||
end)
|
|
||||||
|
|
||||||
return Sash
|
|
||||||
|
|||||||
@@ -1,53 +1,45 @@
|
|||||||
local Widget = require((...):gsub('%.[^.]*$', ''))
|
return function (self)
|
||||||
|
|
||||||
local Slider = Widget:extend()
|
|
||||||
|
|
||||||
function Slider:constructor (layout, data)
|
|
||||||
Widget.constructor(self, layout, data)
|
|
||||||
|
|
||||||
self.value = 0.5
|
self.value = 0.5
|
||||||
|
|
||||||
|
self:onPressDrag(function (event)
|
||||||
|
local x1, y1, x2, y2 = self:getRectangle(true, true)
|
||||||
|
self.value = (event.x - x1) / (x2 - x1)
|
||||||
|
if self.value < 0 then self.value = 0 end
|
||||||
|
if self.value > 1 then self.value = 1 end
|
||||||
|
end)
|
||||||
|
|
||||||
|
self:onDisplay(function (event)
|
||||||
|
local x1, y1, x2, y2 = self:getRectangle(true, true)
|
||||||
|
local padding = self.padding or 0
|
||||||
|
|
||||||
|
local sx1 = math.floor(x1 + self.value * (x2 - x1) - padding) + 0.5
|
||||||
|
local sy1 = math.floor(y1 + padding) + 0.5
|
||||||
|
local sx2 = padding * 2
|
||||||
|
local sy2 = y2 - y1 - padding
|
||||||
|
|
||||||
|
love.graphics.push('all')
|
||||||
|
|
||||||
|
love.graphics.setColor(self.outline)
|
||||||
|
|
||||||
|
love.graphics.rectangle('fill',
|
||||||
|
x1,
|
||||||
|
y1 + ((y2 - y1) / 2),
|
||||||
|
x2 - x1,
|
||||||
|
padding
|
||||||
|
)
|
||||||
|
|
||||||
|
love.graphics.setColor(self.background)
|
||||||
|
|
||||||
|
love.graphics.rectangle('fill', sx1, sy1, sx2, sy2)
|
||||||
|
|
||||||
|
love.graphics.setColor(self.outline)
|
||||||
|
|
||||||
|
love.graphics.rectangle('line', sx1, sy1, sx2, sy2)
|
||||||
|
|
||||||
|
love.graphics.pop()
|
||||||
|
|
||||||
|
return false
|
||||||
|
end)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
Slider:onPressDrag(function (event)
|
|
||||||
local self = event.target
|
|
||||||
local x1, y1, x2, y2 = self:getRectangle(true, true)
|
|
||||||
self.value = (event.x - x1) / (x2 - x1)
|
|
||||||
if self.value < 0 then self.value = 0 end
|
|
||||||
if self.value > 1 then self.value = 1 end
|
|
||||||
end)
|
|
||||||
|
|
||||||
Slider:onDisplay(function (event)
|
|
||||||
local self = event.target
|
|
||||||
local x1, y1, x2, y2 = self:getRectangle(true, true)
|
|
||||||
local padding = self.padding or 0
|
|
||||||
|
|
||||||
local sx1 = math.floor(x1 + self.value * (x2 - x1) - padding) + 0.5
|
|
||||||
local sy1 = math.floor(y1 + padding) + 0.5
|
|
||||||
local sx2 = padding * 2
|
|
||||||
local sy2 = y2 - y1 - padding
|
|
||||||
|
|
||||||
love.graphics.push('all')
|
|
||||||
|
|
||||||
love.graphics.setColor(self.outline)
|
|
||||||
|
|
||||||
love.graphics.rectangle('fill',
|
|
||||||
x1,
|
|
||||||
y1 + ((y2 - y1) / 2),
|
|
||||||
x2 - x1,
|
|
||||||
padding
|
|
||||||
)
|
|
||||||
|
|
||||||
love.graphics.setColor(self.background)
|
|
||||||
|
|
||||||
love.graphics.rectangle('fill', sx1, sy1, sx2, sy2)
|
|
||||||
|
|
||||||
love.graphics.setColor(self.outline)
|
|
||||||
|
|
||||||
love.graphics.rectangle('line', sx1, sy1, sx2, sy2)
|
|
||||||
|
|
||||||
love.graphics.pop()
|
|
||||||
|
|
||||||
return false
|
|
||||||
end)
|
|
||||||
|
|
||||||
return Slider
|
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
local Widget = require((...):gsub('%.[^.]*$', ''))
|
return function (self)
|
||||||
|
|
||||||
local Stepper = Widget:extend()
|
|
||||||
|
|
||||||
function Stepper:constructor (layout, data)
|
|
||||||
Widget.constructor(self, layout, data)
|
|
||||||
|
|
||||||
self.flow = 'x'
|
self.flow = 'x'
|
||||||
self.index = 1
|
self.index = 1
|
||||||
@@ -58,6 +53,5 @@ function Stepper:constructor (layout, data)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
updateValue()
|
updateValue()
|
||||||
end
|
|
||||||
|
|
||||||
return Stepper
|
end
|
||||||
|
|||||||
@@ -1,9 +1,3 @@
|
|||||||
local Widget = require((...):gsub('%.[^.]*$', ''))
|
return function (self)
|
||||||
|
|
||||||
local Text = Widget:extend()
|
|
||||||
|
|
||||||
function Text:constructor (layout, data)
|
|
||||||
Widget.constructor(self, layout, data)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return Text
|
|
||||||
|
|||||||
Reference in New Issue
Block a user