make widgets identical to their data definitions

This commit is contained in:
airstruck
2015-10-30 05:38:46 -04:00
parent 1c491335f5
commit 62ca5bf50a
7 changed files with 47 additions and 54 deletions

View File

@@ -95,7 +95,7 @@ layout.leftSideBox:addChild {
layout.slidey:onPressDrag(function (event) layout.slidey:onPressDrag(function (event)
layout.progressBar.value = layout.slidey.value layout.progressBar.value = layout.slidey.value
layout.progressBar:reflow() layout.progressBar:reshape()
end) end)
--[[ --[[
@@ -115,14 +115,14 @@ layout:onKeyboard(function(event)
end) end)
]] ]]
layout:onMotion(function (event) layout:onMove(function (event)
local w = event.target local w = event.target
layout.statusbar.text = (w.id or '(unnamed)') .. ' ' .. layout.statusbar.text = (w.id or '(unnamed)') .. ' ' ..
w:getX() .. ', ' .. w:getY() .. ' | ' .. w:getX() .. ', ' .. w:getY() .. ' | ' ..
w:getWidth() .. 'x' .. w:getHeight() w:getWidth() .. 'x' .. w:getHeight()
end) end)
layout.newButton:onMotion(function (event) layout.newButton:onMove(function (event)
layout.statusbar.text = 'Create a new thing' layout.statusbar.text = 'Create a new thing'
return false return false
end) end)

View File

@@ -18,7 +18,7 @@ function Event:bind (target, callback)
end end
local eventNames = { local eventNames = {
'Reshape', 'Display', 'KeyPress', 'KeyRelease', 'TextInput', 'Motion', 'Reshape', 'Display', 'KeyPress', 'KeyRelease', 'TextInput', 'Move',
'Enter', 'Leave', 'PressEnter', 'PressLeave', 'Enter', 'Leave', 'PressEnter', 'PressLeave',
'PressStart', 'PressEnd', 'PressDrag', 'PressMove', 'Press', 'PressStart', 'PressEnd', 'PressDrag', 'PressMove', 'Press',
} }

View File

@@ -69,16 +69,16 @@ function Input:handleTextInput (text, x, y)
}) })
end end
function Input:handleMotion (x, y) function Input:handleMove (x, y)
local widget = self.layout:getWidgetAt(x, y) local widget = self.layout:getWidgetAt(x, y)
local previousWidget = self.previousMotionWidget local previousWidget = self.previousMoveWidget
if not widget.hovered then if not widget.hovered then
if previousWidget then if previousWidget then
previousWidget.hovered = nil previousWidget.hovered = nil
end end
widget.hovered = true widget.hovered = true
end end
self:bubbleEvent('Motion', widget, { self:bubbleEvent('Move', widget, {
target = widget, target = widget,
oldTarget = previousWidget, oldTarget = previousWidget,
x = x, y = y x = x, y = y
@@ -96,11 +96,11 @@ function Input:handleMotion (x, y)
oldTarget = previousWidget, oldTarget = previousWidget,
x = x, y = y x = x, y = y
}) })
self.previousMotionWidget = widget self.previousMoveWidget = widget
end end
end end
function Input:handlePressedMotion (x, y) function Input:handlePressedMove (x, y)
local widget = self.layout:getWidgetAt(x, y) local widget = self.layout:getWidgetAt(x, y)
for button = 1, 3 do for button = 1, 3 do
local originWidget = self.pressedWidgets[button] local originWidget = self.pressedWidgets[button]
@@ -183,7 +183,7 @@ function Input:handleReshape (width, height)
root.width = width root.width = width
root.height = height root.height = height
root:reflow() root:reshape()
end end
return Input return Input

View File

@@ -52,7 +52,7 @@ function Layout:show ()
love.window.setTitle(title) love.window.setTitle(title)
end end
self:manageInput(self.input) self:manageInput(self.input)
root:reflow() root:reshape()
end end
function Layout:hide () function Layout:hide ()
@@ -141,9 +141,9 @@ function Layout:manageInput (input)
end) end)
self:hook('mousemoved', function (x, y, dx, dy) self:hook('mousemoved', function (x, y, dx, dy)
if self.isMousePressed then if self.isMousePressed then
return input:handlePressedMotion(x, y) return input:handlePressedMove(x, y)
else else
return input:handleMotion(x, y) return input:handleMove(x, y)
end end
end) end)
self:hook('keypressed', function (key, isRepeat) self:hook('keypressed', function (key, isRepeat)

View File

@@ -1,9 +1,10 @@
local ROOT = (...):gsub('[^.]*$', '') local ROOT = (...):gsub('[^.]*$', '')
local Base = require(ROOT .. 'base')
local Event = require(ROOT .. 'event') local Event = require(ROOT .. 'event')
local Widget = Base:extend() local Widget = {}
Event.injectBinders(Widget)
Widget.isWidget = true Widget.isWidget = true
@@ -19,46 +20,40 @@ function Widget.register (name, decorator)
Widget.typeDecorators[name] = decorator Widget.typeDecorators[name] = decorator
end end
function Widget:constructor (layout, data) local function new (Widget, layout, self)
local meta = getmetatable(self) self = self or {}
local metaIndex = meta.__index self.type = self.type or 'generic'
self.widgetClass = metaIndex
self.type = 'generic'
self.layout = layout self.layout = layout
self.children = {} self.children = {}
self.position = { x = nil, y = nil } self.position = { x = nil, y = nil }
self.dimensions = { width = nil, height = nil } self.dimensions = { width = nil, height = nil }
self:extract(data)
local meta = setmetatable(self, {
__index = function (self, property)
local value = Widget[property]
if value ~= nil then return value end
local style = self.layout.style
value = style and style:getProperty(self, property)
if value ~= nil then return value end
local theme = self.layout.theme
return theme and theme:getProperty(self, property)
end
})
layout:addWidget(self) layout:addWidget(self)
local widget = self
function meta:__index(property) for k, v in ipairs(self) do
local value = metaIndex[property] self.children[k] = v.isWidget and v or new(Widget, self.layout, v)
if value ~= nil then return value end self.children[k].parent = self
local style = widget.layout.style
value = style and style:getProperty(self, property)
if value ~= nil then return value end
local theme = widget.layout.theme
return theme and theme:getProperty(self, property)
end end
local decorate = self.type and Widget.typeDecorators[self.type] local decorate = Widget.typeDecorators[self.type]
if decorate then if decorate then
decorate(widget) decorate(self)
end end
end
function Widget:extract (data) return self
local children = self.children
-- TODO: get rid of pairs somehow
for k, v in pairs(data) do
if type(k) == 'number' then
children[k] = v.isWidget and v or Widget(self.layout, v)
children[k].parent = self
else
self[k] = v
end
end
end end
function Widget:getPrevious () function Widget:getPrevious ()
@@ -251,18 +246,16 @@ function Widget:getAncestors (includeSelf)
end end
end end
-- Reflow the widget. Call this after changing position/dimensions. -- reshape the widget. Call this after changing position/dimensions.
function Widget:reflow () function Widget:reshape ()
self.position = {} self.position = {}
self.dimensions = {} self.dimensions = {}
Event.Reshape:emit(self, { Event.Reshape:emit(self, {
target = self target = self
}) })
for i, widget in ipairs(self.children) do for i, widget in ipairs(self.children) do
widget:reflow() widget:reshape()
end end
end end
Event.injectBinders(Widget) return setmetatable(Widget, { __call = new })
return Widget

View File

@@ -22,9 +22,9 @@ return function (self)
nextSibling[dimension] - event[axis]) nextSibling[dimension] - event[axis])
end end
prevSibling:reflow() prevSibling:reshape()
nextSibling:reflow() nextSibling:reshape()
self:reflow() self:reshape()
end) end)
end end

View File

@@ -24,7 +24,7 @@ return function (self)
self.value = (event.x - x1) / (x2 - x1) self.value = (event.x - x1) / (x2 - x1)
if self.value < 0 then self.value = 0 end if self.value < 0 then self.value = 0 end
if self.value > 1 then self.value = 1 end if self.value > 1 then self.value = 1 end
self:reflow() self:reshape()
end end
self:onPressStart(press) self:onPressStart(press)